		@ME.FORMAT                                                             R








			  Pascal/MT+ T. M.
			    User's Guide
			      Release 5








		      Copyright (c) 1980, 1981

			  Digital Research
			    P.O. Box 579
			     160 Central
		       Pacific Grove, CA 93950
			   (408) 649-3896
			  TWX 910 360 5001

			 All Rights Reserved











			      COPYRIGHT

Copyright (c) 1980, 1981 by Digital Research. All rights reserved.  No
part of this publication may be reproduced, transmitted,  transcribed,
stored  in  a  retrieval  system,  or  translated into any language or
computer  language,  in  any  form   or  by  any  means,   electronic,
mechanical, magnetic, optical, chemical, manual or otherwise,  without
the  prior  written  permission  of  Digital Research, Post Office Box
579, Pacific Grove, California, 93950.

This  manual  is,  however,  tutorial  in  nature. Thus, the reader is
granted permission to  include the example  programs, either in  whole
or in part, in his own programs.


			     DISCLAIMER

Digital Research makes no  representations or warranties with  respect
to  the  contents  hereof  and  specifically  disclaims  any   implied
warranties of merchantability or  fitness for any particular  purpose.
Further,  Digital  Research   reserves  the  right   to  revise   this
publication  and  to  make  changes  from  time to time in the content
hereof without obligation of Digital Research to notify any person  of
such revision or changes.


			     TRADEMARKS

CP/M is a registered trademark of Digital Research.
MP/M, LINK/MT+,  RMAC, Pascal/MT+  and SID  are trademarks  of Digital
Research. Z80 is a registered trademark of Zilog inc. L80 and M80  are
trademarks of Microsoft.

The Pascal/MT+ User's  Guide was prepared  using the Digital  Research
TEX Text  Formatter and  printed in  the United  States of  America by
Commercial Press/Monterey.















		   Fourth Printing: February 1982

				 ii



			  Table of Contents

Chapter 1:  Pascal/MT+ introduction and overview . . . . . . . . . .	1

1.1	  How to use this manual . . . . . . . . . . . . . . . . . .	2
1.2	  System overview  . . . . . . . . . . . . . . . . . . . . .	4
1.3	  System requirements  . . . . . . . . . . . . . . . . . . .	5
1.4	  Run-time requirements  . . . . . . . . . . . . . . . . . .	5
1.5	  Pascal/MT+ distribution disk information . . . . . . . . .	6
1.6	  Minimum configuration  . . . . . . . . . . . . . . . . . .	10

Chapter 2:  How to operate the Pascal/MT+ system . . . . . . . . . .	13

2.1	  Compile and run a sample program . . . . . . . . . . . . .	13

2.2	  COMPILER operation . . . . . . . . . . . . . . . . . . . .	18
2.2.1	  Invocation and filenames . . . . . . . . . . . . . . . . .	18
2.2.2	  Compiler command line switches . . . . . . . . . . . . . .	18
2.2.3	  Compilation data . . . . . . . . . . . . . . . . . . . . .	20
2.2.4	  Compiler toggles . . . . . . . . . . . . . . . . . . . . .	21
2.2.4.1   Entry point record generation(e) . . . . . . . . . . . . .	21
2.2.4.2   Recursion and stack frame allocation (s) . . . . . . . . .	21
2.2.4.3   Include files (i)  . . . . . . . . . . . . . . . . . . . .	21
2.2.4.4   Setting the stack pointer (z)  . . . . . . . . . . . . . .	22
2.2.4.5   Strict type and portability checking (t,w) . . . . . . . .	22
2.2.4.6   Run-time range checking (r)  . . . . . . . . . . . . . . .	22
2.2.4.7   Run-time exception checking (x)  . . . . . . . . . . . . .	22
2.2.4.8   Listing controls (1,p) . . . . . . . . . . . . . . . . . .	23
2.2.4.9   Space reduction: real arithmetic   (c) . . . . . . . . . .	23
2.2.4.10  Space reduction: recursion  (qn) . . . . . . . . . . . . .	23
2.2.4.11  Symbol table space reduction (k) . . . . . . . . . . . . .	23
2.2.4.12  Toggle summary . . . . . . . . . . . . . . . . . . . . . .	25
2.2.5	  Error messages . . . . . . . . . . . . . . . . . . . . . .	26

2.3	  LINKER operation . . . . . . . . . . . . . . . . . . . . .	27
2.3.1	  Invocation . . . . . . . . . . . . . . . . . . . . . . . .	27
2.3.2	  Linker option switches . . . . . . . . . . . . . . . . . .	27
2.3.2.1   Run-time libray search (/s). . . . . . . . . . . . . . . . 	27
2.3.2.2   Memory map (/m)  . . . . . . . . . . . . . . . . . . . . . 	28
2.3.2.3   Load maps (/l), (/e) . . . . . . . . . . . . . . . . . . . 	28
2.3.2.4   Program (/p) and data (/d) origin  . . . . . . . . . . . .	28
2.3.2.5   Hex output (/h) . .. . . . . . . . . . . . . . . . . . . .	29
2.3.2.6   Linker input command file (/f) . . . . . . . . . . . . . .	29
2.3.2.7   Overlay switches . . . . . . . . . . . . . . . . . . . . .	29
2.3.2.8   Linker switch summary  . . . . . . . . . . . . . . . . . .	30
2.3.3	  What relocatable files are required? . . . . . . . . . . .	31
2.3.4	  Linker error messages  . . . . . . . . . . . . . . . . . .	31
2.3.5	  Attributes of linkable modules . . . . . . . . . . . . . .	32
2.3.6	  Using other linkers  . . . . . . . . . . . . . . . . . . .	32

2.4	  DISASSEMBLER   . . . . . . . . . . . . . . . . . . . . . .	33
2.4.1	  Instructions   . . . . . . . . . . . . . . . . . . . . . .	33
2.4.2	  Sample   . . . . . . . . . . . . . . . . . . . . . . . . .	34




				 iii



2.5	  DEBUGGER . . . . . . . . . . . . . . . . . . . . . . . . .	41
2.5.1	  Instructions . . . . . . . . . . . . . . . . . . . . . . .	41
2.5.2	  Command format . . . . . . . . . . . . . . . . . . . . . .	42

2.6	  LIBRARIAN, Lib/MT  . . . . . . . . . . . . . . . . . . . .	45
2.6.1	  Invocation and input files . . . . . . . . . . . . . . . .	45
2.6.2	  Use as a librarian . . . . . . . . . . . . . . . . . . . .	45
2.6.3	  Use as a converter to L80 format . . . . . . . . . . . . . 	46

Chapter 3:  Pascal/MT+ language extentions . . . . . . . . . . . . .	49

3.1	  Modular compilation  . . . . . . . . . . . . . . . . . . .	50

3.2	  Pascal/MT+ : assembly interfacing  . . . . . . . . . . . .	54
3.2.1	  Assemblers . . . . . . . . . . . . . . . . . . . . . . . .	54
3.2.2	  Naming considerations  . . . . . . . . . . . . . . . . . .	54
3.2.3	  Variable accessing . . . . . . . . . . . . . . . . . . . . 	55
3.2.3.1	  Assembly language entry points from Pascal . . . . . . . .	55
3.2.3.2	  Pascal entry points from assembly language . . . . . . . .	55
3.2.4	  Data allocation  . . . . . . . . . . . . . . . . . . . . .	55
3.2.5	  Parameter passing  . . . . . . . . . . . . . . . . . . . .	57
3.2.6	  Restrictions . . . . . . . . . . . . . . . . . . . . . . .	58
3.2.7	  Assembly language interface example  . . . . . . . . . . . 	58

3.3	  Pascal/MT+ OVERLAYS  . . . . . . . . . . . . . . . . . . .	61
3.3.1     Definition of overlays . . . . . . . . . . . . . . . . . .	61
3.3.2     Linking overlays and root programs . . . . . . . . . . . .	63
3.3.2.1   Overlay area switch /v . . . . . . . . . . . . . . . . . .	63
3.3.2.2   Overlay group switch /o  . . . . . . . . . . . . . . . . .	63
3.3.2.3   Overlay local storage /x:  . . . . . . . . . . . . . . . .	64
3.3.2.4   Linking main program . . . . . . . . . . . . . . . . . . .	64
3.3.2.5   Linking an overlay . . . . . . . . . . . . . . . . . . . .	65
3.3.2.6   Overlay filenames  . . . . . . . . . . . . . . . . . . . .	66
3.3.2.7   Linking a program with overlays  . . . . . . . . . . . . .	66
3.3.3     Overlay operational description  . . . . . . . . . . . . .	68
3.3.3.1   Declaring an overlay procedure . . . . . . . . . . . . . .	68
3.3.3.2   Calling an overlay procedure . . . . . . . . . . . . . . .	68
3.3.3.3   Overlays calling other overlays  . . . . . . . . . . . . .	69
3.3.3.4   Access to root program symbols . . . . . . . . . . . . . .	69
3.3.4     Error messages . . . . . . . . . . . . . . . . . . . . . .	70
3.3.5     Example  . . . . . . . . . . . . . . . . . . . . . . . . .	70

3.4	  BUILT-IN PROCEDURES AND FUNCTIONS  . . . . . . . . . . . .	75
3.4.1	  MOVE,MOVERIGHT, MOVELEFT . . . . . . . . . . . . . . . . .	76
3.4.2	  EXIT . . . . . . . . . . . . . . . . . . . . . . . . . . .	78
3.4.3	  @CMD . . . . . . . . . . . . . . . . . . . . . . . . . . .	79
3.4.4	  TSTBIT, SETBIT, CLRBIT . . . . . . . . . . . . . . . . . .	80
3.4.5	  SHR, SHL . . . . . . . . . . . . . . . . . . . . . . . . .	81
3.4.6	  HI, LO, SWAP . . . . . . . . . . . . . . . . . . . . . . .	82
3.4.7	  ADDR . . . . . . . . . . . . . . . . . . . . . . . . . . .	83
3.4.8	  SIZEOF . . . . . . . . . . . . . . . . . . . . . . . . . .	84
3.4.9	  FILLCHAR . . . . . . . . . . . . . . . . . . . . . . . . .	85
3.4.10	  LENGTH . . . . . . . . . . . . . . . . . . . . . . . . . .	86
3.4.11	  CONCAT . . . . . . . . . . . . . . . . . . . . . . . . . . 	87
3.4.12	  COPY . . . . . . . . . . . . . . . . . . . . . . . . . . .	88


				 iv


3.4.13	  POS  . . . . . . . . . . . . . . . . . . . . . . . . . . .	89
3.4.14	  DELETE . . . . . . . . . . . . . . . . . . . . . . . . . .	90
3.4.15	  INSERT . . . . . . . . . . . . . . . . . . . . . . . . . .	91
3.4.16	  ASSIGN . . . . . . . . . . . . . . . . . . . . . . . . . .	92
3.4.17	  WNB, GNB . . . . . . . . . . . . . . . . . . . . . . . . .	94
3.4.18    BLOCKREAD,  BLOCKWRITE . . . . . . . . . . . . . . . . . .	95
3.4.19    OPEN . . . . . . . . . . . . . . . . . . . . . . . . . . .	96
3.4.20    CLOSE  . . . . . . . . . . . . . . . . . . . . . . . . . .	97
3.4.21    PURGE  . . . . . . . . . . . . . . . . . . . . . . . . . .	98
3.4.22    IORESULT . . . . . . . . . . . . . . . . . . . . . . . . .	99
3.4.23	  SEEKREAD, SEEKWRITE  . . . . . . . . . . . . . . . . . . .	100
3.4.24	  READHEX, WRITEHEX  . . . . . . . . . . . . . . . . . . . .	101
3.4.25	  MEMAVAIL, MAXAVAIL . . . . . . . . . . . . . . . . . . . .	102
3.4.26	  WAIT . . . . . . . . . . . . . . . . . . . . . . . . . . .	103
3.4.27	  RIM85, SIM85 . . . . . . . . . . . . . . . . . . . . . . .	104
3.4.28	  Quick reference guide to built-ins . . . . . . . . . . . .	105

3.5	  Chaining . . . . . . . . . . . . . . . . . . . . . . . . .	107

3.6	  Interrupt procedures . . . . . . . . . . . . . . . . . . .	109

3.7	  Non-standard data access methods . . . . . . . . . . . . .	112
3.7.1	  INP and OUT arrays . . . . . . . . . . . . . . . . . . . .	112
3.7.2	  Redirected input/output method . . . . . . . . . . . . . .	112
3.7.3	  Absolute variables . . . . . . . . . . . . . . . . . . . .	113

3.8	  Inline and Mini assembler  . . . . . . . . . . . . . . . .	114
3.8.1	  Syntax . . . . . . . . . . . . . . . . . . . . . . . . . .	114
3.8.2	  Code examples  . . . . . . . . . . . . . . . . . . . . . .	115
3.8.3	  Constant data generation . . . . . . . . . . . . . . . . . 	116

3.9	  Recursion and non-recursion  . . . . . . . . . . . . . . .	117

Chapter 4:  Run-time error handling  . . . . . . . . . . . . . . . .	119

4.1	  Range checking . . . . . . . . . . . . . . . . . . . . . .	120
4.2	  Exception checking . . . . . . . . . . . . . . . . . . . .	120
4.3	  User supplied  handlers  . . . . . . . . . . . . . . . . .	120
4.4	  I/O error handling . . . . . . . . . . . . . . . . . . . .	121

Chapter 5:  Anatomy of a Pascal/MT+ program  . . . . . . . . . . . .	123

5.1	  Data types . . . . . . . . . . . . . . . . . . . . . . . .	123
5.1.1	  CHAR . . . . . . . . . . . . . . . . . . . . . . . . . . .	123
5.1.2	  BOOLEAN  . . . . . . . . . . . . . . . . . . . . . . . . .	123
5.1.3	  INTEGER  . . . . . . . . . . . . . . . . . . . . . . . . .	124
5.1.4	  REAL . . . . . . . . . . . . . . . . . . . . . . . . . . .	124
5.1.5	  BYTE . . . . . . . . . . . . . . . . . . . . . . . . . . .	125
5.1.6	  WORD . . . . . . . . . . . . . . . . . . . . . . . . . . .	125
5.1.7	  STRING . . . . . . . . . . . . . . . . . . . . . . . . . .	126
5.1.7.1	  Definition . . . . . . . . . . . . . . . . . . . . . . . .	126
5.1.7.2	  Assignment . . . . . . . . . . . . . . . . . . . . . . . .	126
5.1.7.3	  Comparisons. . . . . . . . . . . . . . . . . . . . . . . .	128
5.1.7.4	  Reading and writing strings  . . . . . . . . . . . . . . .	129
5.1.8	  SET. . . . . . . . . . . . . . . . . . . . . . . . . . . .	129



				 v


5.2	  Execution time COM file structure  . . . . . . . . . . . .	130
5.2.1	  Memory layout and system variables . . . . . . . . . . . .	130
5.2.2	  Hardware stack size  . . . . . . . . . . . . . . . . . . .	130
5.2.3	  Program structure  . . . . . . . . . . . . . . . . . . . .	131

Chapter 6:  Stand-alone operation of a program . . . . . . . . . . .	133

Chapter 7:  Pascal/MT+ language definition . . . . . . . . . . . . .	137

7.1	  Introduction . . . . . . . . . . . . . . . . . . . . . . .	137

7.2	  Summary of the Pascal/MT+ language . . . . . . . . . . . .	138

7.3	  Notation, terminology, and vocabulary  . . . . . . . . . .	140

7.4	  Identifiers, numbers, and strings  . . . . . . . . . . . .	141

7.5	  Constant definitions . . . . . . . . . . . . . . . . . . .	142

7.6	  Data type definitions  . . . . . . . . . . . . . . . . . .	143
7.6.1	  Simple types . . . . . . . . . . . . . . . . . . . . . . .	143
7.6.1.1	  Scalar types . . . . . . . . . . . . . . . . . . . . . . .	143
7.6.1.2	  Standard types . . . . . . . . . . . . . . . . . . . . . .	143
7.6.1.3	  Subrange types . . . . . . . . . . . . . . . . . . . . . .	144
7.6.2	  Structured types . . . . . . . . . . . . . . . . . . . . .	144
7.6.2.1	  Array types  . . . . . . . . . . . . . . . . . . . . . . .	144
7.6.2.2	  Record types . . . . . . . . . . . . . . . . . . . . . . .	145
7.6.2.3	  Set types  . . . . . . . . . . . . . . . . . . . . . . . .	145
7.6.3	  Pointer types  . . . . . . . . . . . . . . . . . . . . . .	146
7.6.4	  Types and assignment compatibility . . . . . . . . . . . .	146

7.7	  Declarations and denotations of variables  . . . . . . . .	148
7.7.1	  Entire variables . . . . . . . . . . . . . . . . . . . . .	148
7.7.2	  Component variables  . . . . . . . . . . . . . . . . . . .	148
7.7.2.1	  Indexed variables  . . . . . . . . . . . . . . . . . . . .	148
7.7.2.2	  Field designators  . . . . . . . . . . . . . . . . . . . .	149
7.7.2.3	  File buffers . . . . . . . . . . . . . . . . . . . . . . .	149
7.7.3	  Referenced variables . . . . . . . . . . . . . . . . . . .	149

7.8	  Expressions  . . . . . . . . . . . . . . . . . . . . . . .	150
7.8.1	  Operators  . . . . . . . . . . . . . . . . . . . . . . . .	150
7.8.1.1	  The operator NOT . . . . . . . . . . . . . . . . . . . . .	150
7.8.1.2   Multiplying operators  . . . . . . . . . . . . . . . . . .	150
7.8.1.3   Adding operators . . . . . . . . . . . . . . . . . . . . .	151
7.8.1.4	  Relational operators . . . . . . . . . . . . . . . . . . .	151
7.8.2	  Function designators . . . . . . . . . . . . . . . . . . .	151
7.9	  Statements . . . . . . . . . . . . . . . . . . . . . . . .	153
7.9.1	  Simple statements  . . . . . . . . . . . . . . . . . . . .	153
7.9.1.1   Assignment statements  . . . . . . . . . . . . . . . . . .	153
7.9.1.2	  Procedure statements . . . . . . . . . . . . . . . . . . .	153
7.9.1.3	  GOTO statements  . . . . . . . . . . . . . . . . . . . . .	153
7.9.2	  Structured  statements . . . . . . . . . . . . . . . . . .	154
7.9.2.1	  Compound statments . . . . . . . . . . . . . . . . . . . .	154





				 vi


7.9.2.2	  Conditional statements . . . . . . . . . . . . . . . . . .	155
7.9.2.2.1 IF statements  . . . . . . . . . . . . . . . . . . . . . .	155
7.9.2.2.2 CASE statements. . . . . . . . . . . . . . . . . . . . . .	155
7.9.2.3   Repetitive statements. . . . . . . . . . . . . . . . . . .	155
7.9.2.3.1 WHILE statements . . . . . . . . . . . . . . . . . . . . .	156
7.9.2.3.2 REPEAT statements. . . . . . . . . . . . . . . . . . . . .	156
7.9.2.3.3 FOR statements . . . . . . . . . . . . . . . . . . . . . .	156
7.9.2.4	  WITH statements. . . . . . . . . . . . . . . . . . . . . .	156

7.10	  Procedure declarations . . . . . . . . . . . . . . . . . . 	157
7.10.1	  Standard procedures  . . . . . . . . . . . . . . . . . . .	158
7.10.1.1  File handling procedures . . . . . . . . . . . . . . . . . 	158
7.10.1.2  Dynamic allocation procedures. . . . . . . . . . . . . . .	159
7.10.1.3  Data transfer procedures . . . . . . . . . . . . . . . . .	159
7.10.2	  Forward  . . . . . . . . . . . . . . . . . . . . . . . . .	159
7.10.3	  Conformant arrays. . . . . . . . . . . . . . . . . . . . .	159

7.11	  Function declarations	 . . . . . . . . . . . . . . . . . .	161
7.11.1	  Standard functions . . . . . . . . . . . . . . . . . . . .	161
7.11.1.1  Arithmetic functions . . . . . . . . . . . . . . . . . . .	161
7.11.1.2  Predicates . . . . . . . . . . . . . . . . . . . . . . . .	161
7.11.1.3  Transfer functions . . . . . . . . . . . . . . . . . . . .	161
7.11.1.4  Further standard functions . . . . . . . . . . . . . . . .	161

7.12	  Input and Output . . . . . . . . . . . . . . . . . . . . .	163
7.12.1	  The procedure READ . . . . . . . . . . . . . . . . . . . .	163
7.12.2	  The procedure READLN . . . . . . . . . . . . . . . . . . .	163
7.12.3	  The procedure WRITE  . . . . . . . . . . . . . . . . . . .	163
7.12.4	  The procedure WRITELN  . . . . . . . . . . . . . . . . . .	163
7.12.5	  Additional procedures  . . . . . . . . . . . . . . . . . .	164

7.13	  Programs . . . . . . . . . . . . . . . . . . . . . . . . .	165

Appendix A: Pascal/MT+ file I/0. . . . . . . . . . . . . . . . . . .
Appendix B: Error messages . . . . . . . . . . . . . . . . . . . . .	199
Appendix C: Reserved words . . . . . . . . . . . . . . . . . . . . .	207
Appendix D: Language syntax description  .  .  .  .  .  .  . . . . .	209
Appendix E: Library routines . . . . . . . . . . . . . . . . . . . .	217
Appendix F: AMD9511 hardware math chip interface . . . . . . . . . .	221
Appendix G: Direct operating system access . . . . . . . . . . . . .	223
Appendix H: Inter-processor portabiliy . . . . . . . . . . . . . . .	225
Appendix I: Bibliography . . . . . . . . . . . . . . . . . . . . . .	227
Appendix J: Heap management  . . . . . . . . . . . . . . . . . . . .	229
Appendix K: Mini-assembler mnemonics . . . . . . . . . . . . . . . .	231

INDEX  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .	237












				 vii





CHAPTER 1: PASCAL/MT+ INTRODUCTION AND OVERVIEW

      Welcome to the world  of Pascal/MT+t.m. This document  describes
a professional tool which is being used at thousands of installations,
worldwide.  Pascal/MT+  supports  the  entire  International Standards
Organization  (ISO)  standard,  DPS/7185  including  variant  records,
sets,  typed  and  text  files,  passing  procedures  and functions as
parameters, GOTO out  of a procedure,  conformant arrays, and  program
parameters.  The  following  is  a  list  of additions to the standard
supported by Pascal/MT+.

	Additional predefined scalars: BYTE, WORD, STRING
	Expressions may contain the predeclared INP array
	Assignments may be made to the predeclared OUT array
	Switchable non-recursion (default is non-recursion)
	Operators on integers & (and), !,I (or), and 	(not)
	Else on CASE statement
	Interrupt and External procedures
	Additional built-in procedures and functions
	  bit and byte manipulation
	  fast file I/O
	  random file access
	  Move and fill procedures
	  address and sizeof functions
	  string manipulation
	  heap management aids
	BCD and floating point reals
	Modular compilation facilities
	Redirectable I/O facilities (user written char I/O)

      Pascal/MT+  is  designed  both  for data processing applications
(compilers,  editors,  linkers,  and  business packages) and real-time
control applications  (measurment systems,  communications processors,
video tape  controllers, etc.).  All Pascal/MT+  software is  suitable
for using in a ROM-based  environment and is designed to  operate with
or without  an operating  system. Various  software manufacturers make
Pascal/MT+ compatible software such as data base access methods.

      The purpose  of this  chapter is  to present  an overview of the
contents of the  manual, a system  overview, host system  requirements
and run-time  system requirements,  and to  describe the  files on the
distribution  disk  as  well  as  the  minimum set needed to compile a
program.

      Because of the complex nature  of Pascal as a language,  and the
availability  of  many  textbooks,  we  are  not  providing   tutorial
documentation  but  rather   a  reference  chapter   and  a   detailed
description of extensions and additions which make Pascal/MT+  unique.
However, Appendix A contains a tutorial on files in the




  All Information Presented Here is Proprietary to Digital Research

				  1





Pascal/MT+  system.  Please  refer  to  the  bibliography and choose a
textbook if you do not know the Pascal language.

1.1	HOW TO USE THIS MANUAL
	----------------------

    o WILL IT WORK ON MY SYSTEM?
      The answer to this question is in Sections 1.3 and 1.4
      of this chapter. A description of the host requirements
      for running the compiler and linker is found in Section
      1.3. Section 1.4 describes the run-time environment
      needed to execute programs compiled by the
      Pascal/MT+ system.

    o GETTING STARTED
      To check that your software operates as it should,
      follow the directions for bringing up the software
      and compiling a program in Section 2.1.

    o USING THE COMPILER
      For compiler options and directives read Section 2.2.
      Larger programs may be broken into small compiled units
      called modules which are treated in Section 3.1.
      Compile-time errors are treated in Chapter 2 and in the appendix.

    o USING THE LINKER
      Section 2.3 describes the operation of the linker.
      Also, when you are familiarlwith the options provided by
      the linker the overlay scheme for large programs is
      discussed in Section 3.3.

    o USING THE DEBUGGER
      Debugger instructions are found in Section 2.5.

    o USING THE DISASSEMBLER
      Section 2.4 contains information on the disassembler.

    o USING THE LIBRARIAN
      The librarian instructions are given in Section 2.6.

    o WHAT DOES THE PASCAL/MT+ LANGUAGE PROVIDE?
      Chapter 7 is the definition of the Pascal/MT+ language,
      based on Jensen and Wirth's 'User Manual and Report'.
      Chapter 7 is a description of the ISO and MT+ features
      which are not implemented in the Jensen and Wirth Pascal.
      This chapter is not sufficient by itself to learn Pascal.
      If you do not yet know Pascal, use Jensen & Wirth or any
      Pascal textbook as a supplement when studying this chapter.
      See the bibliography.

    o HOW ARE THE PASCAL/MT+ EXTENSIONS USED?
      The answer to this question is found in Chapter 3. All of
      the extensions are described with examples and suggestions.

  All Information Presented Here is Proprietary to Digital Research

				  2



    o FILE I/0 (including console and printer I/0)
      Pascal/MT+ file I/O is presented in Appendix A in tutorial
      format with many program samples. The file access procedures
      which are not part of the standard Pascal are discussed in
      Section 3.4 as well as in the appendix. Some notes on file
      access are also found in Section 7.12. Fast I/O routines are
      described in 3.4 and in Appendix A.

    o REAL NUMBERS
      The format of real numbers is found in 5.1. Use of the
      AMD9511 hardware math chip is discussed in the appendix.
      The software floating point real number library is
      FPREALS.ERL, and the BCD real number library is BCDREALS.ERL.

    o RECURSION
      Sections 2.2.4.10 and 3.10 indicate how to use recursion and
      what to watch for when using recursion. Check the index for
      the effects of recursion on various features of the language.

    o PUTTING A PROGRAM INTO ROM
      Information on stand-alone operation of object code is found
      in Chapter 6.

    o ASSEMBLY LANGUAGE INTERFACING
      Section 3.2 describes how modules written in assembly
      language and compiled to Microsoft compatile files may
      be interfaced with Pascal/MT+ programs.

    o RUN-TIME ERROR HANDLING
      Sections 2.2.4.6 and 2.2.4.7 and Chapter 4 discuss Pascal/MT+
      run-time error handling.

    o SYNTAX DIAGRAMS, KEYWORDS
      The Pascal/MT+ BNF syntax diagrams are found in Appendix D
      and in Chapter 7 as each feature of the language is presented.
      A list of keywords is found in Appendix C.

    o PROGRAM STRUCTURE
      The structure of a program generated by the compiler is presented
      in Chapter 5. Data storage is also presented in this chapter.
      Section 3.3 describes the structure of a program which is using
      overlays.

      Digital  Research   has  endeavored   to  produce   a  complete,
integrated package  of software  tools and  we are  presently creating
additional tools for  use with this  package. If you  have suggestions
for  improving  any  Digital  Research'  product,  please  WRITE  US A
LETTER.   We  evalutate,  and  often  implement,  user suggestions and
comments. All  suggestions become  the property  of Digital  Research,
Inc.





  All Information Presented Here is Proprietary to Digital Research

				  3



1.2	SYSTEM OVERVIEW
	---------------

      The   Pascal/MT+   system    contains   a   compiler,    linker,
disassembler,  debugger,  run-time  subroutine  library,  and optional
editor package. Figure  1 shows a  diagram of the  relationships among
these programs.


(any CP/M compatible editor may be used including our
SpeedProgramming (tm) editor, which includes a syntax scanner).

    +------+
    |editor|
    +------+
      |		(temporary file created and deleted by the compiler)
      V        /
    +----------+
    | compiler |<---- error message text file
    +----------++
	|	|
	V	+-> relocatable file   [run-time-library]
    listing		|	|      |     also [other user modules]
      file		|	V      V
	|		|     +--------+
	|		|     | linker |<---- [optional debugger]
	|		|     +--------+
	|		|	    |
	|		|	    V
	|		|	executable program
	|		|	(optional symbol table)
	|		|
	V		V
    +-----------------------+
    |     disassembler      +---> intermixed source and assembly code
    +-----------------------+

	      Schematic Diagram of Pascal/MT+ Operation

      The  user  executes  the  compiler  to translate source programs
into relocatable machine code. Then  the user links this machine  code
with the run-time subroutine  library to produce an  executable object
program.  If  desired,  a  "listing"  file  from  the compiler and the
relocatable file  may be  combined into  a intermixed  file of  source
code  and  assembly  code  using  the  disassembler. The user may also
inform the compiler that use of the symbolic debugger is desired.  The
compiler and linker will then output an executable object module  with
the symbolic debugger included.  Facilities such as variable  display,
breakpoints and  tracing are  available using  the symbolic  debugging
package.





  All Information Presented Here is Proprietary to Digital Research

				  4





1.3	SYSTEM REQUIREMENTS
	-------------------

      The  Pascal/MT+  system  requires  an  8080,  8085,  or Z808 CPU
running the CP/M operating system  (release 1.4 or later) in  which to
operate. Other  operating systems  which claim  to be  CP/M compatible
may be  used but  the responsibility  for compatibility  lies with the
user.

      In  a   CP/M  environment,   the  compiler   requires  92K    of
simultaneous  on-line  storage.  The  Pascal/MT+ compiler requires 36K
bytes of  memory in  which to  reside. The  compiler symbols occupy 4K
bytes  of  symbol  table  space  (this  number may be changed using $K
toggles to eliminate  unused symbols) and  still more space  is needed
for user symbols.  For example, the  largest module of  the Pascal/MT+
compiler  requires  17K  of  symbol  table  space.  This  means that a
minimum recommended TPA (transient program  area) of 43K is needed  to
compile small  programs (allowing  3K for  user symbols).  A 48K  CP/M
system, in most cases, provides this minimum TPA. If the entry to  the
BDOS  is  higher  than  ABFF  you  have  enough  room to compile small
programs.  However,  a  48K  TPA  is  recommended as a minimum working
environment.  Additional  memory,  if  present,  will automatically be
used.

      The linker  requires only  11K bytes  of disk  and memory space.
Because it  uses memory  for linking  programs and  run-time routines,
the amount of  available memory limits  the program size  which can be
linked.  A   59K  TPA   (maximum  available   memory  for   a  minimum
configuration  64K  CP/M)  has  approximately  49K bytes of work space
after  the  linker  and  linker  data  is loaded. This work space must
contain the symbol table and the  object code. In addition, if the  /D
switch is not used  it must also contain  the data area. Overlays  can
be used when the program becomes to large to link in one step

1.4	RUN-TIME REQUIREMENTS
	---------------------

      The  Pascal/MT+  system  generates  programs  which  utilize   a
variety  of  run-time  support  subroutines  which  are extracted from
PASLIB, the run-time  library, and other  relocatable modules.   These
run-time routines  handle such  needs as  "multiply" and  "divide" and
file input and output interface to the operating system.  CP/M 2.0  or
a later release is required to use random access files.

      For programs which are run  under the CP/M operating system  the
minimum run-time overhead  is typically in  the 2K- to  6K-byte range.
This  includes  support  routines  and  text  file  I/O  routines  for
integer, characters and strings.  Additional modules will be  included
for  routines  which   utilize  REAL  numbers,   non-text  file   I/O,
transcendental  routines,  etc.   Below  are  the  current approximate
sizes  (in  1024  byte  units)  of  the run-time libraries and support
modules.  These numbers are subject to change without notice.  If  you
need a very accurate view of run-time overhead, link the

    All Information Presented Here is Proprietary to Digital Research

				  5




individual file, ignore  the undefined references,  and note the  code
and data size at the end of the link.

	File		Code	Data	Total
	PASLIB*		16.8	2.3	19.1*
	FPREALS**	6.1	0.5	6.6
	TRANCEND	2.5	0.3	2.8
	BCDREALS**	2.3	0.1	2.4
	FULLHEAP***	1.8	0.1	1.9
	RANDOMIO	2.1	0.1	2.2
	DEBUGGER+	7.9	1.2	9.1
	REALIO++	4.0	0.4	4.4
	FPRTNS		0.8	0.1	0.9
	TRAN9511	0.4	0.1	0.5

      * normally only the referenced routines are linked using
	only 2 to 6 K bytes
     **	only one of these are used for software real number support.
	FPREALS is searchable, BCDREALS is not searchable
    ***	used for ISO heap management; PASLIB contains a smaller
	version for UCSD style heap management
      +	when used, compiler generates extra code; never contained
	in final version of program
     ++ counted in FPREALS already, used only for AMD9511 support
    +++ used only for AMD9511 support

1.5	PASCAL/MT+ DISTRIBUTION DISK INFORMATION
	----------------------------------------

      The  Pascal/MT+  software  package   is  distributed  on   media
compatible  with  your  computer  (tape,  diskette,  etc.) The package
consists  of  a  number  of  CP/M  files containing object, source and
relocatable files. Listed below are  the names of all of  these files,
a brief description of  their contents and a  list of which files  are
required  to  configure  a  minimum  operational disk. These files are
subject to  change without  notice as  later releases  of the software
become available and the contents of the distribution disks change.

FILE		CONTENTS
----		-------
MTPLUS.COM	Pascal/MT+ compiler, executable CP/M file (Phase 0)
		Syntax scanner and listing file generator
		also generates PASTEMP.TOK temporary file
		which is approximately 1/3 the size of
		the source code file. Also uses MTERRS.TXT
		for error message text.
MTERRS.TXT	Ascii text for error messages used by MTPLUS.COM
MTPLUS.000	Root program (a COM file renamed so that it






  All Information Presented Here is Proprietary to Digital Research

				  6




MTPLUS.000	Root program (a COM file renamed so that it
		cannot be executed directly) which calls the
		overlays .001 through .006.
MTPLUS.001	Built-in symbol table initialization.
MTPLUS.002	User Symbol table construction (Phase 1)
MTPLUS.003	Code generator initialization
MTPLUS.004	Object code generator pass (Phase 2)
MTPLUS.005	Code generator termination and external reference
		output
MTPLUS.006	Debugger symbol table output routine
		(actually executed between .002 and .003 overlays)
LINKMT.COM	Pascal/MT+ linker, takes ERL and CMD files as input
		and optionally creates COM, HEX SYM and SYP files.
PASLIB.ERL	Searchable run-time subroutine library in relocatable
		form. Always linked last.
FPREALS.ERL	Software floating point support routines.
		This is a library which contains software
		floating point routines and REALIO.ERL. Searchable
		and must be linked just before PASLIB.
TRANCEND.ERL	Transcendental function support (for software floating
		point only).
BCDREALS.ERL	Business arithmetic support routines (does not include
		square root or trancendentals).
DEBUGGER.ERL	Relocatable code for symbolic debugger
		(linked as main program when used).
DEBUGHELP.TXT	Contains a summary of debugger commands.




























    All Information Presented Here is Proprietary to Digital Research

				  7



DIS808O.COM	Disassembler program. Takes PRN and ERL files as
		input and outputs intermixed listing file to file,
		console or printer. Also handles Z80 instructions
		generated by the compiler. Only usable for Pascal
		programs, not a general purpose disassembler.
LIBMT.COM	Librarian program which inputs BLD and ERL files
		to create searchable libraries OR L80 compatible
		modules.
FULLHEAP.ERL	Complete new and dispose, with garbage collection and
		heap management routines in relocatable form. PASLIB
		contains UCSD-style stack heap routines. This module
		must be linked before PASLIB to use these routines.
ROVLMGR.ERL	Overlay manager assembled with the RELOAD option TRUE.
CALC.SRC	Sample program for testing floating point.
		Useful when using AMD9511 hardware to insure
		proper operation of the 9511.
REALIO.ERL	Read and Write real routines for floating point
		necessary only when using AMD9511 hardware floating
		point routines.




































  All Information Presented Here is Proprietary to Digital Research

				  8



AMDIO.SRC	module containing routines which interface to the
		AMD9511. User must edit and recompile to
		customize for specific hardware requirements.
FPRTNS.ERL	Support routines for AMD9511 hardware floating point
TRAN9511.ERL	Module containing 9511 drivers for transcendental
		functions only for use with hardware floating point
AMD9511.CMD	Linker command file including AMDIO, FPRTNS,
		REALIO and TRAN9511
AMD9511X.CMD	Linker command file including just AMDIO and FPRTNS
UTILMOD.ERL	Module which contains KEYPRESSED, RENAME and EXTRACT
		utility subroutines.
RANDOMIO.ERL	Random I/O routines which are compatible
		with sequential files.

      The  following  run-time  library  subroutines  are  provided in
source code form. Some  of these are supplied  to allow users who  are
running without an operating  system, e.g., without CP/M,  to properly
interface to their hardware. Others are provided so that the user  may
change the  action of  the routines  as they  are performed in PASLIB.
These  routines  are  identical  or  functionally  compatible with the
routines in PASLIB.ERL. Nearly all are supplied in Pascal module  form
so that  users will  not require  an assembler  to implement ROM based
programs in most cases.

PINI.SRC	Initialization routine
CPMRD.SRC	Used by Read string routine (@RST)
		Included because it uses CP/M direct BDOS call.
HLT.SRC		"halt" routine. Current routine calls CP/M.
CHN.MAC		Chaining routine. May be changed to do bank
		switching, etc. as desired in a non-CP/M environment.
		As this is fairly special it is supplied in assembly
		code. NOTE: MOST ROM BASED SYSTEMS WILL NOT USE CHAIN
		AND THEREFORE THE USER NEED NOT HAVE AN ASSEMBLER TO
		CREATE A ROM BASED SYSTEM!
RNC.SRC		Contains read next character routine.
WNC.SRC		Contains write next character routine.
DIVMOD.MAC	Source for DIV and MOD routines which include a
		direct call to CP/M for divide by 0 error message.

















  All Information Presented Here is Proprietary to Digital Research

				  9




FIBDEF.LIB	Include file for PINI, RNC and WNC. Definition
		of the file control block.
OVLMGR.MAC	Overlay manager. User selectable options to allow
		more overlays or to allow overlays to call overlays.
		unmodified version already in PASLIB.
IOERR.SRC	Sample routine for user-handled I/O errors.
XBDOS.SRC	BDOS routine which contains calls to IOERR.
IOCHK.BLD	File to be used to create I/O error library.
RST.MAC		Read string routine.
CWT.MAC		Wait for end-of-line routine.
GET.SRC		Low level input routine.
PUT.SRC		Low level output routine.
@RNB.SRC	Read next byte routine.
@WNB.SRC	Write next byte routine.

1.6	MINIMUM CONFIGURATION
	---------------------

      The  files  listed  below  are  the absolute minimum required to
operate the Pascal/MT+ compiler. They  need not all be present  on the
same disk but  all need to  be on-line. Additional  files such as  the
linker and libraries may be on the same disk but are not necessary  to
operate the compiler. The MTPLUS.006 overlay is only necessary to  use
the debugger and otherwise need not be on-line.

FILE		SIZE
MTPLUS.COM	35k	executable compiler
MTPLUS.000	l3k	root program, calls overlays
MTPLUS.001	llk	}
MTPLUS.002	7k	}
MTPLUS.003	8k	}	overlays for compiler
MTPLUS.004	l7k	}	(always required)
MTPLUS.005	8k	}
MTPLUS.006	6k	only necessary if debugger requested

      The  total  size  required  is  92k,  or  86k if debugger is not
requested. These numbers are subject to change without notice. If  you
cannot fit all of the above files  onto one disk there is a method  by
which the root and overlay  files may reside on another  on-line disk.
This is  done by  using a  compiler command  switch which  informs the
compiler that the root and overlays are on a different













  All Information Presented Here is Proprietary to Digital Research

				 10




drive. See Section 2.2.2.

      The minimum files required to link a program are:

LINKMT.COM	llk linker
PASLIB.ERL	l9k Run-time support library

Other ERL  files may  be required  if calls  are made  to them  from a
Pascal program. See Section 2.3 on the linker which contains the  list
of ERL files supplied  and which ones are  required to be linked  into
your program to resolve references.

If you  have room,  the ideal  configuration is  to place  all of  the
above  files  plus  MTERRS.TXT  (the  error  message text file) on one
disk. The  data can  be on  the same  disk if  there is  room, or on a
second on-line disk.






































  All Information Presented Here is Proprietary to Digital Research

				 11


























































  All Information Presented Here is Proprietary to Digital Research

				 12





	     CHAPTER 2: HOW TO OPERATE THE PASCAL/MT+ SYSTEM
	     -----------------------------------------------

      This chapter describes how to use the major Pascal/MT+  programs
contained on the distribution disk.

   o Step-by-step instructions on how to compile, link, and
     run a sample program are presented  in Section 1.

   o The compiler and compiler options are detailed in Section 2.

   o The linker and its options are described in Section 3.

   o Section 4 instructs the user in how to create the input for
     the disassembler and shows a sample output from that program.

   o The fifth section describes the debugger and what
     Instructions are available.

   o Section 6 presents instructions on how to use the librarian.


2.1	COMPILE AND RUN A SAMPLE PROGRAM
	--------------------------------

      Before compiling  and running  the sample  program described  in
this section, MAKE  A BACKUP of  all of the  disks included with  this
software release.

      The following is a step-by-step guide to the basic operation  of
the  Pascal/MT+  system.  You  will  create  a  system  compiler disk,
compile, link, and execute a  sample program under the CP/M  operating
system. If  you have  problems with  compilation or  linking, read the
rest of  the manual  for further  help before  calling or writing your
distributor.

      The following discussion assumes that the computer on which  you
are about to execute Pascal/MT+  has two 8-inch single density  floppy
disks.  If  you  have  other  than  this  configuration, then make the
appropriate adjustments.  Please read  all of  the steps  below before
attempting to  operate the  software so  you have  an idea  of what is
being done.











  All Information Presented Here is Proprietary to Digital Research

				 13




	The following 7 files are required to compile CALC.

	MTPLUS.COM		Executable compiler
	MTPLUS.000		Root program
	MTPLUS.001	}
	MTPLUS.002	}
	MTPLUS.003	}	Overlays for the compiler
	MTPLUS.004	}
	MTPLUS.005	}

	MTERRS.TXT is not mandatory but is useful.
	It contains error messages.

	The following four files are used to link CALC.ERL (generated
	by the compiler) to create an executable CALC.COM:

	LINKMT.COM		Linker
	TRANCEND.ERL		Transcendental function module
	FPREALS.ERL		Floating point real library
	PASLIB.ERL		Pascal run time library

1)     Make a disk which  contains the compiler, MTPLUS.COM,  the root
program,  MPLUS.000,   and  the   overlay  files   MTPLUS.001  through
MTPLUS.005. Also useful  but not necessary  to be placed  on this disk
is  MTERRS.TXT.  Put  a  CP/M  system  on your new compiler disk using
SYSGEN or a similar program.

      Create  another  disk   which  contains  LINKMT.COM,   CALC.SRC,
FPREALS.ERL, TRANCEND.ERL,  and PASLIB.ERL.  This contains  all of the
files necessary to link CALC.

2)     Place the disk now  containing the compiler and  CP/M into your
'A:' drive.

3)    Place  your  disk  containing  CALC.SRC,  LINKMT.COM,  and   the
ERL files into the 'B:1 drive.

4)    Boot your system and remain logged into the 'A:' drive.

5)      Type  the  following  command  (<cr>  signifies you typing the
return key on your system keyboard)

		MTPLUS B:CALC<cr>

CALC should compile free  of syntax and semantic  errors.  If you  get
errors of this type  you probably have a  bad copy and should  re-copy
CALC from your masters and try again.







  All Information Presented Here is Proprietary to Digital Research

				 14



      Depending on  your memory  and hardware  configuration, you  may
get memory limitation errors  or disk write errors.  Memory limitation
errors are  either 'recursion  stack overflow'  or error  407 which is
symbol  table  overflow.  Section  2.2.5  describes  what steps may be
taken to alleviate these errors. If you get a disk write error in  the
first pass such  as 'Error writing  PASTEMP.TOK, disk probably  full.'
then use  the $T  command switch  discussed in  Section 2.2.2. You may
get errors  writing out  CALC.ERL which  means you  need more space on
your data disk.

      Another  type  of  error  which  may  be  encountered  in   this
compilation is that the overlay manager cannot find a procedure in  an
overlay or cannot find an overlay. It will generate a '?' followed  by
the name of the procedure or overlay which is missing. If the  overlay
is missing, check  that it is  the correct name  and is on-line.  If a
procedure  is  missing,  the  file  which  contains it is corrupt. See
Section 2.2.5.

6)     The compiler should  load and display  the message  'Pascal/MT+
V.xx' where  'V' is  the version  number and  'xx' is  the sub-release
number for the  version of the  software which you  have. The compiler
should  process  the  CALC  program  by  displaying the following: (or
something close,  we reserve  the right  to change  without reprinting
all the manuals).

	Pascal/MT+	Release V.xx
	(c) 1981 Digital Research, Inc.

	CP/M-80 version
	+++++				{syntax / token file generation}
	Source lines:		109
	V.xx Phase 1
	Available Memory:	nnnnn	{total symbol table space}
	User Table Space:	nnnnn	{after predefined symbols}
	####				{one # for each routine body}
	Remaining Memory:	nnnnn	{after user symbols}
	V.xx Phase 2
	8080
	SUBREAL 18
	ADDREAL 54
	TF	88			{decimal offset from beginning}
	CALC	161
	MENU	1096
	CALCULAT

	Lines		:	109
	Errors:	0
	Code		:	2050
	Data		:	48
	Pascal/MT+ V.xx Compilation Completed





  All Information Presented Here is Proprietary to Digital Research

				 15



7)     After  the compilation  is complete  verify that  the  compiler
properly placed the  CALC.ERL file on  the destination disk  by typing
'DIR B:CALC.ERL' and having the CP/M system display:

			     B: CALC    ERL

8)    Now to link the programl Type 'B:' to log into the B drive.  You
will see the B> prompt. Type the following command to the linker:

		  LINKMT CALC,TRANCEND,FPREALS,PASLIB/S

followed by the return  key. The linker should  find no errors in  the
.ERL files  it is  linking. If  any errors  such as  'Duplicate symbol
found'  or  'Undefined  symbols'  are  listed,  one or more of the ERL
files is bad. Recopy all of  the files from the master and  re compile
CALC and link again before contacting your distributor. If you have  a
disk  write  error  you  probably  do  not  have  enough  room  on the
destination disk. You should see the following output:

		LINK/MT+T.M.V.XX

		Processing file-	CALC    .ERL
		Processing file-	TRANCEND.ERL
		Processing file-	FPREALS .ERL
		Processing file-	PASLIB  .ERL

		Undefined Symbols:

		No Undefined Symbols

		nnnn (decimal) records written to CALC    .COM

		Total Data: nnnnH bytes
		Total Code: nnnnH bytes
		Remaining : nnnnH bytes

		Link/MT+ processing completed

9)     Now  verify that  the linker  placed the  CALC.COM file  on the
destination  disk  by  typing:   IDIR  CALC.COMI  and  receiving   the
response:

			     B: CALC    .COM

from CP/M.










  All Information Presented Here is Proprietary to Digital Research

				 16



10)   Now to run the  program! The output from CALC and user  input as
described in this paragraph are  shown below. User input is  in single
quotation marks.  CALC is  using the  default ISO  standard formatting
which  you  may  change  in  your  own  programs with formatting write
statements.

		'B:CALC'
		ENTER FIRST OPERAND? '5.5<CR>'
		Rl= 5.50000E+00

		ENTER SECOND OPERAND? '99.256<CR>'
		R2= 9.92560E+01

		ENTER OPERATOR
		S:SIN C:COS A:ARCTAN L:LN E:EXP 1:SQR $SQRT

		+, -, *, / ARITHMETIC OPERATORS

		M:NEGATE
		=:EQUAL N:NOT EQUAL
		<:LESS THAN >:GREATER THEN
		Z:LESS THAN OR EQUAL TO
		G:GREATER THAN OR EQUAL TO
		4:TRUNC 5:ROUND

		? '+'

		104.756

		TYPE <ESCAPE> TO STOP

  All Information Presented Here is Proprietary to Digital Research

				 17





2.2	COMPILER OPERATION
	------------------

2.2.1	INVOCATION and FILENAMES


      The  compiler  is  named  MTPLUS.COM  and  uses  a root program,
MTPLUS.000, and five overlays  plus the debugger overlay.  Input files
may be  located on  any disk  and the  names are  standard CP/M names.
Input files must have a carriage  return, line feed, and control Z  at
the end.  The filename  is one  to eight  characters long  and may  be
preceeded by a drive letter  ('A'..'P', '@' for the logged-in  disk) .
The filename  may have  any extension  but if  specified with  a blank
extension, e.g., TEST1, and not found with a blank extension then  the
compiler  will  search  for  a  file  with a SRC extension followed by
searching for a file with a  PAS extension. If no match is  made, then
an error message will be  issued: 'Unable to open input  file.' MTPLUS
creates  a  relocatable  file  <name>.ERL  which  must  be linked with
LINK/MT+ to the routines in the runtime package.

	To execute the Pascal/MT+ compiler type:

       MTPLUS <filename> {optional parameters preceeded by $ or #}

For example,  'MTPLUS CALC'  puts CALC.ERL  to the  default drive  and
IMTPLUS  CALC  $RBI  puts  CALC.ERL  on  drive B:. See Section 2.3 for
details regarding linking.

2.2.2	COMPILER COMMAND LINE SWITCHES


      The compiler  accepts a  number of  "option switches"  following
the  name  of  the  input  f  ile  on  the command line. These options
switches are in the form of a string preceeded by a '$' (dollar  sign)
character or a '#' character  and are single letters followed  by zero
or more parameter characters. The parameter string extends from the  $
to the  end of  the line  and spaces  are ignored,  i.e., $PXRB is the
same  as  $PX  RB.  Listed  below  are  the switches and their default
values. The 'd' parameter indicates  where the output file is  routed.
When 'd' is 'X'  it is routed to  the console, when 'd'  is 'P' output
is routed to the printer, and for  'd' equal to '@' or 'A'..'O' it  is
sent to a standard CP/M disk drive.













  All Information Presented Here is Proprietary to Digital Research

				 18





SWITCH	MEANING				  DEFAULT
------	-------				  -------

Rd	Put the ERL file on 'd:1	  Put ERL with source
	d=@,A..O

Od	MTPLUS.000, the root program.	  Root and overlays on
	and MTPLUS.001 through		  default disk.
	MTPLUS.006 are on drive 'd:'
	d=@,A..O

Pd	Put the	PRN (listing file)	  no .PRN file
	on disk 'd'. d= X,P,@,A..O

X	Generate an eXtended REL file	  nonextended .REL file
	including disassembler records	  generated

D	Generate debugger information	  no debugger information
	in the object code and write	  and no PSY file
	the .PSY file to the drive	  are generated
	specified by the R option

Ed	The MTERRS.TXT file is on 'd:'	  MTERRS.TXT on default disk
	d= @,A..O

Td	Put the PASTEMP.TOK file on 'd:'  PASTEMP on default disk
	d= @,A..O

Q	Quiet, suppress any unnecessary	  Compiler is verbose
	console messages

C	Continue on error, default is to  Compiler stops and asks on
	pause and let operator interact	  each error.
	on each error, one at a time.

A	Automatically call the linker at  Compiler does not
	the end of compilation. A .CMD	  automatically chain
	CMD file with the same name as
	the input program is required.
	Linker must be named 'LINKMT.COM'.

B	Use BCD rather than floating	   Floating point reals
	point for the real numbers

Z	Generate Z80 optimized code	   Generate only 8080 code

V	Print the name of each procedure   Each procedure name not
	and function when found in source  printed
	code as an aid to determining
	error locations during PHASE 0.

@	The '@' character is made	   '@' not equivalent to '^'
	equivalent to the '^' character.

  All Information Presented Here is Proprietary to Digital Research

				 19



      An  example  which   executes  the  compiler,   reads the source
from the A:  drive, places the  .ERL file on  B:, the PRN  file on the
console, and automatically calls the linker is as follows:

		       MTPLUS A:TESTPROG $RB PX A


2.2.3	COMPILATION DATA


      The  Pascal/MT+  compiler  will  periodically  output characters
during the first two phases of  the compilation (Phase 0 and Phase  1)
to keep the user happy knowing  that the compiler has not gone  off to
meet its maker. See 2.1, the compilation of CALC, for sample  compiler
output.

      A '+' is printed to  the console for every 16  source-code lines
syntax  scanned  during  Phase  0.  At  the  beginning  of PHASE 1 the
available memory space is displayed.  This is the number of  bytes (in
decimal)  of   memory  before   generation  of   the  symbol    table.
Approximately  4K  bytes  of  symbol  table  space  is consumed by pre
defined identifiers. See  Section 2.2.4.11 on  reducing this space  by
eliminating unneeded declarations of built-in routines. At the end  of
this phase, the User table space is displayed in decimal. This is  the
amount of  memory left  for user  symbols and  the compiler  recursion
stack  after  the  compiler  symbols  are  loaded. When a procedure or
function is found a  '#' is output to  the console. At the  completion
of PHASE 1, the  number of bytes remaining  in memory is displayed  in
decimal.

      PHASE 2 generates object code.  When the body of each  procedure
is encountered, the name of the  procedure is output so that the  user
can  see  where  the  compiler  is  in the compilation of the program.
Following the name is the offset  from the beginning of the module  in
decimal. This is output when the procedure/f unction body is  actually
encountered, e.g., if A contains  B which contains C, then  the output
would be C  followed by B  followed by A.  The linker /M  (Map) option
will list  the absolute  addresses of  the procedures  in each module.
Upon encountering an error, the  line will be displayed and  if MTERRS
is on-line, a  description of the  error is written  at the bottom  of
the  screen.  If  MTERRS  is  not  on-line,  just  the error number is
written. This  number may  be looked  up in  the appendix to determine
the meaning of the error.  See Section 2.2.5 for further  information.
Upon completion the following lines are displayed:

		Lines :	lines of source code compiled (in decimal)
		Errors:	number of errors detected
		Code  :	bytes of code generated (in decimal)
		Data  :	bytes of data reserved (in decimal).






  All Information Presented Here is Proprietary to Digital Research

				 20




2.2.4	COMPILER TOGGLES

      The compiler toggle  signals the compiler  that the user  wishes
to enable or disable  certain options.  The  format of this toggle  is
(*$____*)  or  {$_______}  where  the  blanks  are  filled in with the
toggle. One toggle per comment  is allowed, e.g. (*$E+*) is  legal but
(*$E+ $S+*) is not legal.  The compiler does not accept blanks  before
the key letter or trailing or  imbedded blanks in names but will  skip
over leading blanks, e.g.,  {$E +} is the  same as {$E+}, but  {$ E +}
will be ignored.

	EXAMPLES:

	(*$E+*)
	{$P}
	{$I D:USERFILE.LIB}

2.2.4.1	Entry Point Record Generation (E)

      $E  controls  the  generation  of  entry  point  records  in the
relocatable file.  $E+ causes the global variables and all  procedures
and functions to be available  as entry points, i.e., available  to be
referenced by EXTERNAL declarations  in other modules.   $E- supresses
the  generation  of  these   records,  thus  causing  the   variables,
procedures, and functions to  be logically private, The  default state
is $E+ and the toggle may be turned on and off at will.

2.2.4.2	Recursion and Stack Frame Allocation (S)

      $S+  enables  stack  frame  allocation  of  procedure / function
parameters  and  local  variables.  It's  default is non-recursion. It
must  be  used  in  modules  and  programs  which  contain   recursive
procedures or  functions. This  toggle must  be turned  on before  the
word PROGRAM or  MODULE and cannot  be turned off  within a separately
compiled  unit.  Global  variables  in  either programs or modules are
always allocated statically. Modules which use $S+ may be linked  with
modules which do not use $S+ into a single program.

2.2.4.3	Include Files 	(I)

	$I<filename> causes the compiler to include the named file  in
the  sequence  of  Pascal  source  statements.  Filename specification
includes drive  name and  extension in  CP/M standard  format. If  the
extension is not given, the  extension from the main file  is assumed.
The file must have a carriage return, line feed, and control Z at  the
end of the file to be included properly into the input stream.  Nested
include statements (one included  source file includes another  source
file) are not legal.







  All Information Presented Here is Proprietary to Digital Research

				 21





2.2.4.4	Setting the Stack Pointer (Z)

      The $Z $nnnn toggle is  used to initialize the stack  pointer to
nnnnH in non-CP/M  environments.  In  a CP/M environment  the hardware
stack is initialized  by loading the  value in absolute  location 0006
into  the  stack  pointer  register.  If  the  $Z toggle is used, then
generation of the CP/M  type initialization is supressed.  This toggle
must be placed before  the BEGIN line in  the main program. It  is not
needed in separate modules, but only once in the main program.

2.2.4.5		Strict Type and Portability Checking 	(T,W)

      $T+, $T-,  $W+ and  $W- control  the strict  type checking / non
portable warning facility. These  features are tightly coupled,  i.e.,
strict  type  checking  implies  warning  non-portable  usage and visa
versa.  The  default  state  is  $T-  ($W-)  in which type checking is
relaxed and warning  messages are not  generated. If these  checks are
on and a nonportable feature is encountered during the compilation  of
the source,  error message  500 is  generated. Note  that because  the
STRING data type  is NOT standard,  string operations will  cause this
error when the W / T switch is on.

      This switch is designed to check for compatibility with the  ISO
Pascal standard.  It does  not check  for all  features listed  in the
appendix  on  portability  because  many  of  them  are implementation
dependent or are software routines.

      This  toggle  may  be  turned  on  and off throughout the source
code as desired.

2.2.4.6		Run-time Range Checking 	(R)

      $R+ and $R- control  the compiler's generation of  run-time code
which will perform  range checking on  array subscripting and  storing
into  subrange  variables.  The  default  state  is $R- (off) and this
toggle  may  be  turned  on  and  off  throughout  the  source code as
desired. See Chapter 4 for further information.

2.2.4.7		Run-time Exception Checking 	(X)

      Exception  checking  is  performed  on  integer  and  real  zero
divide, string overflow, real  number overflow and underflow.  $X+ and
$X-  control  the  compiler's  generation  of run-time code which will
perform run-time  error checking  and error  handling. This  switch is
default ON,  and in  the current  release, turning  it off is ignored.
The user  is directed  to Chapter  4 for  more discussion  of run-time
error handling and options.







  All Information Presented Here is Proprietary to Digital Research

				 22



2.2.4.8	Listing Controls 	(L,P)

      The $P  and $L+,  $L- toggles  control the  listing generated by
the first  pass of  the compiler.  $P will  cause a formfeed character
(CHR(12)) to be inserted  into the PRN file.  $L+ and $L- are  used to
switch the listing  on and off  throughout the source  program and may
be placed wherever desired.

2.2.4.9	Space Reduction: Real Arithmetic 	(C)

      The  $Cn  toggle  can  be  used  by  the user to reduce run-time
object code memory requirements  when using REAL arithmetic.  The user
can,  if  available,  specify  a  restart  instruction  number and the
compiler  will  then  change  all  calls  to the @XOP routine,the real
utility load and store routine, into a restart instruction. This  will
cause all  three byte  call instructions  to shrink'to  one byte  call
instructions.  The  user  specifies  In'  in  the  range  0..7 and the
compiler  generates  RST  n  instructions.  In a CP/M environment, the
restarts which are not  available because of CP/M  usage are 0 and  7.
Mp/MT.M.users and others  should consult their  hardware documentation
for more details.

      The $C toggle  requires that the  toggle be present  in both the
modules which use this feature and in the main program. It must be  in
the main program so  that the compiler may  generate code to load  the
restart vector and  generate restart instructions  for calls to  @XOP.
It  must  be  in  modules  which  use  real  numbers  so  the  restart
instruction is generated.

2.2.4.10	Space Reduction: Recursion 	(Qn)

      In a similar manner to the  $Cn toggle, the $Qn toggle has  been
added  to  perform  the  same  operation  (short calls) with recursive
modules. The letter n is in the range of 0..7. Every call to the  @DYN
routine used for loads and stores will be converted to a restart.  For
example, restart 5 will be used if (*$Q 5*) is specified.

      The $Q toggle  requires that the  toggle be present  in both the
modules which use this feature and in the main program. It must be  in
the main program so  that the compiler may  generate code to load  the
restart vector and  generate restart instructions  for calls to  @DYN.
It must be in modules  which use recursion so the  restart instruction
is generated.

2.2.4.11 Symbol Table Space Reduction (K)

      The  $Kn  toggles  are  used  to  remove  unreferenced  built-in
routine definitions from the symbol  table to make more room  for user
symbols. Any reference to the removed symbols generates an  'undefined
identifier'  error  message.  They  have  nothing  to do with what the
linker loads. The value n (0..15) is used to control




  All Information Presented Here is Proprietary to Digital Research

				 23



various groups of routines. These  may be used in any  combination but
these toggles  MUST appear  before the  word PROGRAM  or MODULE  to be
effective. Only one $K toggle per  comment is allowed. The value n  is
selected as follows:

	GROUP	ROUTINES REMOVED
	-----	---------------
	0	ROUND, TRUNC, EXP, LN, ARCTAN
		SQRT, COS, SIN
	1	COPY, INSERT, POS, DELETE, LENGTH
		CONCAT
	2	GNB, WNB, CLOSEDEL, OPENX, BLOCKREAD
		BLOCKWRITE
	3	CLOSE, OPEN, PURGE, CHAIN, CREATE
	4	WRD, HI, LO, SWAP, ADDR, SIZEOF, INLINE,
		EXIT, PACK, UNPACK
	5	IORESULT, PAGE, NEW, DISPOSE
	6	SUCC, PRED, EOF, EOLN
	7	TSTBIT, CLRBIT, SETBIT, SHR, SHL
	8	RESET, REWRITE, GET, PUT, ASSIGN, MOVELEFT,
		MOVERIGHT, FILLCHAR
	9	READ, READLN
	10	WRITE, WRITELN
	11	< unused >
	12	MEMAVAIL, MAXAVAIL
	13	SEEKREAD, SEEKWRITE
	14	RIM85, SIM85, WAIT
	15	READHEX, WRITEHEX



























  All Information Presented Here is Proprietary to Digital Research

				 24




2.2.4.12	Toggle Summary

	COMPILER TOGGLES				DEFAULT
	----------------				-------

	$E +/-	  Controls entry point generation 	$E+

	$S +/-	  Controls recursive/static variables 	$S-

	$I <name> Includes another source file into
	  	  the input stream, e.g., {$I XXX.LIB}

	$R +/-	  Controls range checking code		$R-

	$T +/-
	$W +/-	  Controls strict typechecking and
	  	  generation of warning messages	$T-
							$W-
	$X +/-	  Controls eXception checking code	$X-

	$P	  Enter a formfeed in the PRN file

	$L +/-	  Controls the listing of source code 	$L+

	$Kn	  Allows for Killing built-in routines
	  	  to save space in symbol table (n=O7)

	$Z $nnnn  Initialize hardware stack to nnnnH
	  	  default is contents of location 0006
	  	  at the begining of execution)

	$Cn	  Use RST n instructions for REAL operations
	  	  default is to use CALL instructions)
	$Qn	  Use RST n instructions for loads and
	  	  stores in recursive environments.
	  	  default is to use CALL instructions)

  All Information Presented Here is Proprietary to Digital Research

				 25



2.2.5	ERROR MESSAGES

      Compilation  errors  are  numbered  in  the  same  sequence  and
meaning as those in Jensen  and Wirth's 'User Manual and  Report'. The
errors messages, brief explanations, and some causes of the error  are
found in the appendix.

      The compiler asks  whether you would  like to abort  or continue
compiling after each error it finds (unless the command line C  switch
described in Section 2.2.2 is used).

      If the compiler cannot find an overlay or a procedure within  an
overlay it will display  a question mark followed  by the name of  the
procedure or overlay which is missing.

	EXAMPLES

	?A:MTPLUS.003	{this form for missing file}
	?"PH2TERM"	{this form for corrupted file}

A missing overlay can be alleviated  by making sure it is the  correct
name and is on-line. The  Od switch (Section 2.2.2) may  be necessary.
If the  routine cannot  be found,  you have  a corrupted  copy of  the
overlay.

      Below  are  procedure  names  which  would  be  displayed by the
compiler if it  could not locate  the names in  the entry point  table
for the overlay in which they  are supposed to be located. The  number
in  front  of  the  name  is  the  group  number  of the overlay which
contains the procedure.

		001	INITIALI
		002	PHASE1
		003	PH21NIT
		004	BLK
		005	PH2TERM
		006	DBGWRITE

      Error 407, Symbol  Table Overflow :  Occurs in Phase  I when not
enough symbol table space remains for the current symbol. This may  be
alleviated  by  1)  using  $K  toggles,  2)  breaking the program into
modules.

      Recursion  Stack  Overflow:   Occurs  in  Phase   II  when   the
compiler's  expression  evaluation  stack  'collides'  with the symbol
table.  This  may  be  alleviated  by  following the suggestions given
above as well as 1)  simplifying expressions, 2) changing sparse  CASE
statements  into  IF-THEN-ELSE  statements  because  the  jump   table
generated by the CASE can become large.






  All Information Presented Here is Proprietary to Digital Research

				 26




2.3	LINKER OPERATION
	----------------

2.3.1 	INVOCATION

      LINK/MT+ is  invoked by  typing its  name, followed  by a space,
followed by the  main program and  modules to be  linked, separated by
commas. Below is the syntax for the linker command line.

 LINKMT {<main program>=}<main program>,<module(s)>,PASLIB{<switches>}

All files to  be linked must  have the ERL  extension (except the  CMD
file  described  in  the  next  section)  but  this  extension  is not
specified in the linker's input file list. A maximum of 32 file  names
may be given  to the linker  as input. The  output is directed  to the
same disk  as the  main program  unless the  user specifies  an output
file name  followed by  an equal  sign before  the main,program  name.
Each  file  to  be  linked  may  also  be preceeded by a drive letter.
Examples are shown below:

   LINKMT CALC,TRANCEND,FPREALS,PASLIB/S
   LINKMT B:CALC=CALC,B:TRANCEND,FPREALS,PASLIB/S {CALC.COM to B:}

2.3.2	LINKER OPTION SWITCHES

      The  linker  allows  the  user  to  place a number of "switches"
following the file  names in the  list. Each switch  is preceded by  a
slash (/) and is a single letter  with a parameter on the P, D,  V, X,
and 0 switches. The only placement sensitive switch is /S.

2.3.2.1	Run-time Libray Search 	(/S)

      The examples  in the  previous section  show the  use of  the /S
switch  which  commands  the  linker  to  search  the previously named
relocatable  file,  PASLIB  in  the  above  example,  as a library and
extract  only  the  necessary  modules.  The  /S  switch only extracts
modules from libraries and  does not extract procedures  and functions
from separately compiled modules. It is position dependent in that  it
must follow  the name  of the  run-time library  in the linker command
line. PASLIB and FPREALS  are specially constructed libraries  so that
they are searchable. Other ERL files supplied with the system,  unless
explicitly specified,  are not  searchable. User  created modules  are
not searchable unless  they have been  processed by LIB/MT,  described
in Section 2.6.  The order of  modules within a  library is important.
Each searchable  library must  contain routines  in the  correct order
and be followed by /S for searching to occur (see 2.6.).








  All Information Presented Here is Proprietary to Digital Research

				 27




2.3.2.2		Memory Map 	(/M)

      A  /M  following  the  last  file  named  in  the parameter list
generates a map to the console.

2.3.2.3		Load Maps (/L), (/E)

      A  /L  following  the  last  module  named  causes the linker to
display module code  and data locations  as they are  being linked.  A
/E  following  the  last  module  causes  the  linker  to  display all
routines  including  those  which  begin  with  $,  ?, or @, which are
reserved for run-time library routine names.

2.3.2.4		Program (/P) and Data (/D) Origin

      In order to  support relocation of  object code and  data areas,
the linker supports the  /P and /D switches.   The /P switch  controls
the location of the object code  (ROM) and the /D switch controls  the
location of the data  area (RAM) . The  syntax is: /P:nnnn or  /D:nnnn
where "nnnn" is a hexadecimal number in the range O..FFFF.  These  two
switches are used in the linking of main programs and overlays.

      Also,  if  /D  is  used,  more  space  is  gained in the linking
process because  the data  is not  intermixed with  the code  as it is
being  linked.  Using  this  switch   is  one  way  to  solve   memory
limitations. The user should note  that local file operations are  not
guaranteed if this is used because the system depends upon the  linker
zeroing the data area to make this facility work properly.

      Using the /P switch and /D  switch does not cause the linker  to
leave empty space at the beginning of the COM file. Other linkers  (in
particular L80T.M.) will generate  a significant amount of  disk space
to  force  the  program  to  load  at  the  proper  address  in a CP/M
environment. The philosophy  of LINK/MT+ is  that if the  /P switch is
used the user really wants to  move the program to another system  for
execution. This  means that  if the  user specifies  /P:8000 the first
byte of  the COM  file  will  be  the  byte to  be placed  at location
8000H and not 32K of zeroes before the first byte.

      These  switches,  /P  and  /D,  are  specified  after  the  last
relocatable file to be loaded and may be in any order.












  All Information Presented Here is Proprietary to Digital Research

				 28



2.3.2.5	Hex Output 	(/H)

	The  /H:nnnn  switch  is  provided  to  allow  the  linker  to
generate a HEX file  instead of a COM  file. The nnnn value  is in HEX
and is  totally independent  of the  default relocation  value of 100H
(possibly overridden by the /P  switch). This means that the  user may
relocate the program  to execute at  1DOOH, for example,  but generate
the HEX file to have addresses starting at 8000H. (The user would  use
/P:lDOO/H:8000).

2.3.2.6	Linker Input Command File 	(/F)

      The user  in a  CP/M environment  must typically  use the SUBMIT
facility  for  typing  repetitive  sequences  such as linking multiple
files together  over and  over and  over again.   The LINK/MT+  linker
allows the user  to enter this  data into a  file and have  the linker
process the  file names  from the  file. This  process is considerably
faster than submit. The user must specify a file with an extension  of
CMD and follow this  file name with a  /F, e.g., CFILES/F. The  linker
will read input from this file and process the names. Names may be  on
one line separated by commas as you would type it on the terminal,  or
each name or group of names may be on a separate line. The input  from
the file  is concatenated logically  between the  data on  the left of
the file name and  the data on the  right of the /F  switch. The total
input buffer to the linker may be 256 bytes. The example below uses  a
CMD file to link the files CALC, TRANCEND, FPREALS, and PASLIB into  a
COM file.  The command  to link  the files  would be  LINKMT CALC/F/L.
PASLIB is searched for  only the necessary modules  and a link map  is
generated.

       CALC.CMD contains : A:CALC,D:TRANCEND,F:FPREALS,B:PASLIB/S

2.3.2.7	Overlay Switches

      Three switches  are used  when the  linker is  processing a root
program in  an overlay  scheme or  is processing  an overlay.  Because
overlays are treated  in detail in  Section 3.3, only  a brief summary
of overlay switches is presented here.

      The  first  is  /Vm:nnnn  which  gives the overlay area address.
The  second  is  /X:nnnn  which  tells  the linker how much extra data
space is required by the overlays.  The value is added to SYSMEM,  the
heap  pointer.  The  third  is  /O:n  which  numbers  the  overlay and
indicates  that  the  previous  filename  is  the  root program symbol
table.










  All Information Presented Here is Proprietary to Digital Research

				 29




2.3.2.8 Linker Switch Summary

	/S	-	Search preceding name as a library
			extracting only the required routines

	/L	-	List modules as they are being linked

	/M	-	List all entry points in tabular form

	/E	-	List entry points beginning with $, ? or @
			in addition to other entry points

	/P:nnnn		Relocate object code to nnnnH

	/D:nnnn		Relocate data area to nnnnH

	/W	-	Write a SID T.M. compatible SYM file
			(written to the same disk as the COM file)

	/H:nnnn		Write the output as a HEX file with
			nnnnH as the starting location for the
			hex format. This is totally independent of
			the /P switch (no COM file produced if
			this switch is used)

	IF		Take preceding file name as a CMD file
			containing input file names (one per line)

	/Vm:nnnn -	Overlay area starting address

	/X:nnnn	-	Overlay static variable space added to SYSMEM

	/O:n	-	number the overlay and use the previous
			filename as the root program symbol table. By
			default, n is in 1-50 but may be extended to
			1..256 by altering the overlay manager.


















  All Information Presented Here is Proprietary to Digital Research

				 30




2.3.3	WHAT RELOCATABLE FILES ARE REQUIRED?

      The distribution disks contain  many ERL files which  are linked
into your  program depending  on what  groups of  routine the compiler
must reference based on the contents of your program. Below is a  list
of each file  and the routines  that it contains.  If you have  any of
these routines  as an  undefined reference  then link  the appropriate
relocatable file to resolve the reference.

	BCDREALS	BCD real numbers, @XOP,@RRL,@WRL

	FPREALS		Floating point real numbers
			@XOP,@RRL,@WRL (searchable)
	AMDIO
	FPRTNS
	REALIO		Hardware real numbers (SEE AMD9511.CMD)

	One of the above groups must be linked when any real number
	loads, stores, assignments, or input/output is performed.

	TRANCEND	Support for SIN, COS
			ARCTAN, SQRT, LN, EXP, SQR
	TRAN9511	Transcendental routines for 9511 replaces
			TRANCEND.
	RANDOMIO	SEEKREAD and SEEKWRITE are resolved here.
	DEBUGGER	@NLN, @EXT, @ENT generated when debugger
			switch is requested. If @XOP and @WRL
			are undefined see Section 2.5.
	PASLIB		Comparisons, I/O, arithmetic support, etc.

2.3.4	LINKER ERROR MESSAGES

      Errors encountered in the linking process include those such  as
funable  to  open  input  file:   xxxxxxxx'  (self  explanatory)   and
'Duplicate  symbol  -  xxxxxxx.1  'Duplicate  symbol' means that a run
time routine or  variable and user  routine or variable  have the same
name. The linker will also output 'duplicate symbol detected'  because
the above message may scroll off the screen.

      If you run out of memory while linking, you may remove the  data
from the code  space with the  /D switch. You  may need to  run a test
link with the D  switch set very high  to find out what  the code size
is,  then  relink  with  the  D  switch  set  just above the last code
address (with some  room for code  expansion). Also, the  $E toggle in
the compiler can  be turned off  around identifiers which  need not be
public. This saves space in the linker's symbol table.








  All Information Presented Here is Proprietary to Digital Research

				 31




      The  error   message  'initialization   of  DSEG   not  allowed'
indicates  that  the  linker  found  a  DB  or DW in the data segment.
'Incompatible relocatable  file' means  that the  ERL file  is bad and
cannot be linked  or that the  assembly language file  is implementing
something illegal.  'SYSMEM not  found in  SYM file'  is printed  when
linking an  overlay and  the root  program symbol  file is  corrupted.
When  linking  assembly  language  modules,  50  external  plus offset
addresses  are  allowed  by  the  linker  in its offset table. If this
number is exceeded then  the message 'External offset  table overflow'
is printed.

2.3.5		ATTRIBUTES OF LINKABLE MODULES

      Link/MT+  will   link  Pascal/MT+   main  programs,   Pascal/MT+
modules, and  assembly language  modules created  by M80  T.M. or RMAC
T.M. Link/MT+  supports those  features of  the Microsoft  relocatable
format required for Pascal/MT+. These do NOT include:

	1) COMMON
	2) Initialized DATA areas in the DATA segment
	3) Request library search

Also  Link/MT+  demands  that  the  data-size and program-size records
preceed the first  byte of data  to be loaded.  This is the  case with
the Pascal/MT+ compiler, M80 and  RMAC but not with such  compilers as
FORTRAN.

2.3.6		USING OTHER LINKERS

      If the  user has  not specified  that the  disassembler is to be
used, then the ERL file produced by the Pascal/MT+ compiler is  almost
Microsoft compatible. It is almost compatible due to undocumented  and
changing requirements for input files to other manufacturers  linkers.
However, processing  the ERL  files produced  by the  compiler by  the
librarian  program,  LIB/MT+,  can  result  in  Microsoft   compatible
relocatable files. See Section 2.6 describing LIB/MT+ for  information
on  this  program.  Other  linkers,  particularly  the L80 linker from
Microsoft,  may  not  be  able  to  link  a program which Link/MT+ can
handle due to memory limitations imposed by the design of these  other
linkers.

  All Information Presented Here is Proprietary to Diqital Research

				 32



2.4 	DISASSEMBLER
	------------

      The disassembler  component of  the Pascal/MT+  package combines
the PRN file  (created by using  the P switch)  produced by the  first
phase  of  the  compiler  with  the  ERL  file (created by using the X
switch)  produced  by  the  last  phase  of  the compiler into a human
readable  file  which  contains  assembly language coding interspersed
with the Pascal/MT+  statements.  This  allows investigation into  the
code produced by the  compiler and provides the  necessary information
when it is required to debug the program at the machine code level.

      Only  a  disassembler  for  8080  mnemonics is provided with all
CP/M-80 releases  because the  majority of  the code  produced by  the
compiler is 8080 code.

2.4.1	INSTRUCTIONS

The  disassembler  is  a  stand-alone  program  which  is  invoked  by
specifying the  name of  the disassembler,  the name  of the PRN file,
the name of the ERL file and the name of the output file:

	    DIS8080 <input name> {<destination name> {,L=nnn}}

      The disassembler  looks for  a ERL  and a  PRN file  with <input
name> as a prefix. The ERL  file must be a specially compiled  version
in which the X  switch has been enabled.  Failing to do so  causes the
entire program  to be  disassembled into  DB statements.  The X switch
generates opcode records for the  disassembler's use. The ERL and  PRN
files may  be on  any disk  but both  must be  on the  same disk.  The
destination file name may be a  CP/M file name or a Pascal/MT+  device
name such as CON: or LST:.  The default destination name is CON:.  The
L=nnn parameter  allows the  user to  specify the  number of lines per
page on the output device. The default value is 66 for 11" paper  with
6-lines-per-inch. This is useful when using printers such as the  T.I.
810 which has  a 6-lines per-inch  or 8-lines-per- inch  switch. Using
8-lines-per-inch  the  user  should  specify  (for 11" paper) that the
paper has 88  lines. This can  save considerable amounts  of paper. To
use the L= option the user MUST specify the <destination name>.

      Error  messages  generated  by  the  disassembler are due to the
fact that it found something unexpected in the bit stream.  Continuing
on usually produces  more errors as  the sequence is  off. A completed
.ERL file should have no errors in it so the correction to be made  is
to re-compile  the ERL  file and  be sure  you are  just disassembling
Pascal code.









  All Information Presented Here is Proprietary to Digital Research

				 33




2.4.2	SAMPLE

      The following Pascal/MT+ program, PPRIME, was compiled with  the
X  and  P  switches  and  disassembled, producing the following output
(for an 8080/Z80):

PROGRAM PPRIME;
CONST
  SIZE=8190;
VAR
  PRIME: ARRAY[O..SIZE] OF BOOLEAN;
  I,J,K,L: INTEGER;
  COUNT: INTEGER;
  CH : CHAR;
  MAX: O..SIZE;





(*$P*)
PROCEDURE TEST1(A,B,C:INTEGER);
BEGIN
  B:=SUCC(SUCC(SUCC(A+A)));
  C:=A+B;
  WHILE C<=MAX DO
    BEGIN
      PRIME[C]:=FALSE;
      C:=C+B;
    END;
END; (* TEST1 *)

(*$P*)
BEGIN
  MAX := SIZE;
  WRITE('G');
  READ(CH);
  FOR L := 1 TO 10 DO
    BEGIN
      COUNT:=O;
      FILLCHAR(PRIME,SIZEOF(PRIME),CHR(TRUE));

      FOR I:=O TO MAX DO
	IF PRIME[I] THEN
	  BEGIN
	    TEST1(I,J,K);
	    COUNT:=SUCC(COUNT);
	  END;
    END;
  WRITELN(COUNT);
  WRITE('E');
END.


  All Information Presented Here is Proprietary to Digital Research

				 34




Output from disassembler:

      The  user  will  note  that  references to program locations are
followed by a  single quote (1000')  and references to  data locations
are followed by a double quote  (0000"). The user will also note  that
the operand of instructions  which reference external variables  point
to the previous  reference and the  final reference contains  absolute
0000. The list of external chains is following the disassembly of  the
program.

Pascal/MT+ 5.00 Copyright (c) 1980 by MT MicroSYSTEMS Page #    1
Disassembly	of: TESTIT

Stmt	Nest	Source Statement / Symbolic Object Code

	PRIME	EQU	0000
	L	EQU	2000
	K	EQU	2002
	i	EQU	2004
	I	EQU	2006
	COUNT	EQU	2008
	CH	EQU	200A
	MAX	EQU	200C
   1	  0   PROGRAM PPRIME;

0000		DB	00,00,00,00,00,00,00,00
0008		DB	00100100100100100,00,00
0010		imp	0000
0013		imp	0000

   2	0	CONST
   3	1	  SIZE=8190;
   4	1	VAR
   5	1	  PRIME: ARRAY[O..SIZE] OF BOOLEAN;
   6	1	  I,J,K,L: INTEGER;
   7	1	  COUNT: INTEGER;
   8	1	  CH : CHAR;
   9	1	  MAX: O..SIZE;
  10	1
  11	1
  12	1
  13	1
  14	1
  15	1	(*$P*)
  16	1
  17	1	PROCEDURE TEST1(A,B,C:INTEGER);
  18	1	BEGIN
     TEST1:
0016		CALL 	0000





  All Information Presented Here is Proprietary to Digital Research

				 35


	0019		POP	H
	001A		SHLD	200E"
	001D		POP	H
	001E		SHLD	2010"
	0021		POP	H
	0022		SHLD	2012"
	0025		CALL	0000

	  19	2	B:=SUCC(SUCC(SUCC(A+A)));

	0028		LHLD	2012"
	002B		XCHG
	002C		LHLD	2012"
	002F		DAD	D
	0030		INX	H
	0031		INX	H
	0032		INX	H
	0033		SHLD	2010"

	  20	2	C:=A+B;

	0036		LHLD	2012"
	0039		XCHG
	003A		LHLD	2010"
	003D		DAD	D
	003E		SHLD	200E"

	  21	2	WHILE C<=MAX DO

	0041		LHLD	200E"
	0044		PUSH	H
	0045		LHLD	20OC"
	0048		PUSH	H
	0049		CALL	0000
	004C		POP	PSW
	004D		JNC	006D'

	  22	2	 BEGIN
	  23	3	   PRIME[C]:=FALSE;

	0050		LXI	H,0000"
	0053		XCHG
	0054		LHLD	200E"
	0057		DAD	D
	0058		PUSH	H
	0059		LXI	H,0000
	005C		XCHG
	005D		POP	H
	005E		MOV	M,E

	  24	3	    C:=C+B;

	005F		LHLD	200E"
	0062		XCHG
	0063		LHLD 	2010"

  All Information Presented Here is Proprietary to Digital Research

				 36


	0066		DAD	D
	0067		SHLD	200E"

	  25	3	  END;

	006A		JMP	0041'

	  26	2      END; (* TEST1 *)

	006D		RET

	  27	1
	  28	1	(*$P*)
	  29	1
	  30	1	BEGIN

	006E		LHLD	0006
	0071		SPHL
	0072		CALL	0000

	  31	1	MAX := SIZE;

	0075		LXI	H,lFFE
	0078		SHLD	20OC"

	  32	1	WRITE('G');

	007B		LXI	H,0000
	007E		PUSH	H
	007F		CALL	0000
	0082		LXI	H,0047
	0085		PUSH	H
	0086		CALL	0000
	0089		CALL	0000

	  33	1	READ(CH);

	008C		LXI	H,200A"
	008F		PUSH	H
	0090		LXI	H,0000
	0093		PUSH	H
	0094		CALL	0080'
	0097		CALL	0000

	  34	1	FOR L := 1 TO 10 DO

	009A		LXI	H,0001
	009D		PUSH	H
	009E		LXI	H,OOOA
	0OAl		PUSH	H
	0OA2		POP	D
	0OA3		POP	H
	0OA4		DCX	H
	0OA5		SHLD	2000"
	0OA8		INX	H

  All Information Presented Here is Proprietary to Digital Research

				 37


	0OA9		PUSH	H
	00AA		PUSH	D
	OOAB		CALL	0000
	OOAE		SHLD	2014"
	0OB1		LHLD	2000"
	0OB4		INX	H
	0OB5		SHLD	2000"
	0OB8		LHLD	2014"
	OOBB		DCX	H
	OOBC		SHLD	2014"
	OOBF		Mov	A,H
	00CO		ORA	L
	00cl		JZ	012C'

	  35	1	  BEGIN
	  36	2	    COUNT:=O;

	0OC4		LXI	H,0000
	0OC7		SHLD 	2008"

	  37	2	FILLCHAR(PRIME,SIZEOF(PRIME),CHR(TRUE));

	OOCA		LXI	H,0000"
	OOCD		PUSH	H
	OOCE		LXI	H,lFFF
	OOD1		PUSH	H
	OOD2		LXI	H,0001
	OOD5		PUSH	H
	OOD6		CALL	0000

	  38	2
	  39	2	    FOR I:=O TO MAX DO

	OOD9		LXI	H,0000
	OODC		PUSH	H
	OODD		LHLD	20OC"
	OOEO		PUSH	H
	OOE1		POP	D
	OOE2		POP	H
	OOE3		DCX	H
	OOE4		SHLD	2006"
	OOE7		INX	H
	OOE8		PUSH	H
	OOE9		PUSH	D
	OOEA		CALL	OOAC'
	OOED		SHLD	2016"
	OOFO		LHLD	2006"
	0OF3		INX	H
	0OF4		SHLD	2006"
	0OF7		LHLD	2016"
	OOFA		DCX	H
	OOFB		SHLD	2016"
	OOFE		MOV	A,H
	OOFF		ORA	L
	0100		JZ	0129'

    All Information Presented Here is Proprietary to Digital Research

				 38



	  40	2	      IF PRIME[I] THEN

	0103		LXI	H,0000"
	0106		XCHG
	0107		LHLD	2006"
	010A		DAD	D
	010B		MOV	A,M
	010C		RAR
	010D		JNC	0126'

	  41	2		BEGIN
	  42	3		  TEST1 (I,J,K)

	0110		LHLD	2006"
	0113		PUSH	H
	0114		LHLD	2004"
	0117		PUSH	H
	0118		LHLD	2002"
	011B		PUSH	H
	Olic		CALL	0013'

	  43	3		  COUNT:=SUCC(COUNT);

	011F		LHLD	2008"
	0122		INX	H
	0123		SHLD	2008"

	  44	3		END;

	0126		JMP	OOFO'

	  45	2	  END;

	0129		JMP	OOBV

	  46	1	WRITELN(COUNT);

	012C		LHLD	2008"
	012F		PUSH	H
	0130		LXI	H,007C'
	0133		PUSH	H
	0134		CALL	0095'
	0137		CALL	0087'
	013A		CALL	0000
	013D		CALL	0000

	  47	1	WRITE('E');

	0140		LXI	H,0131'
	0143		PUSH	H
	0144		CALL	0135'
	0147		LXI	H,0045
	014A		PUSH	H
	014B		CALL	0138'

  All Information Presented Here is Proprietary to Digital Research

				 39


	014E		CALL	008A'

	  48	1 		END.

	0151		CALL	0000

	External reference chain @WIN    --> 013B
	External reference chain @CHW    --> 014F
	External reference chain @RCH    --> 0098
	External reference chain @PST    --> 0017
	External reference chain @PLD    --> 0026
	External reference chain @CRL    --> 013E
	External reference chain @LEI    --> 004A
	External-reference chain @FIN    --> OOEB
	External reference chain @SFB    --> 0145
	External reference chain @DWD    --> 014C
	External reference chain @INI    --> 0073
	External reference chain @HLT    --> 0152
	External reference chain OUTPUT  --> 0141
	External reference chain INPUT   --> 0091
	External reference chain FILLCH  --> OOD7



































  All Information Presented Here is Proprietary to Digital Research

				 40




2.5 	DEBUGGER
	--------

      The Pascal/MT+ debugger, a relocatable file named  DEBUGGER.ERL,
is  a  component  of  the  Pascal/MT+  system which is linked into the
object program along with  the run-time support library.  The debugger
can  display  variables,  set  symbolic  breakpoints,  single  step  a
statement at  a time,  display symbol  tables, and  display entry  and
exit  from  procedures  and  functions.  Line numbers are displayed in
trace mode although  when debugging a  program consisting of  modules,
line  numbers  are  duplicated  in  each  module.  It can be used in a
non-CP/M environment if the user responds with simply <return> to  the
debugger's  request  for  the  symbol  table  (.SYP)  file  name. This
disables  only  the  symbolic  facilities  but  retains the display by
address facilities.

      The following two sections describe how to include the  debugger
code in an object program and how to operate the debugger.

2.5.1	INSTRUCTIONS

      To  include  debugger  information  into  the object program the
user  must  specify  the  D  command  line  switch  to MTPLUS.COM. The
compiler will  then produce  a PSY  file to  the same  disk as the ERL
file  and  generate  extra  code  at  the  beginning  and  end of each
procedure for  the debugger  breakpoint logic.  The PSY  files contain
records  for  each  procedure,  function  and variable declared in the
program.  The  address  fields  for  each  of  these  items  is module
relative. Link/MT+ will process these PSY files and create a SYP  file
containing  absolute  addresses  for  the  procedures,  functions  and
variables. The debugger then uses this SYP file for symbolic  variable
display, symbolic breakpoints, etc.

      Link/MT+  (as  described  above)  creates  a  COM and a SYP file
from the  ERL and  PSY files  created by  the compiler.  The user must
link  the  debugger  as  the  first  module  of  the  program  so that
execution begins with the debugger  when the program is run.  Below is
a sample command  line for the  linker when the  debugger is is  being
linked.

	       LINKMT USERPROG=DEBUGGER,USERPROG,PASLIB/S

The 'USERPROG=' syntax  causes the name  of the COM  file generated by
the linker to be USERPROG and not DEBUGGER.

      Because the  debugger is  in charge  of USERPROG,  it will first
ask for the name of the  symbol table file when USERPROG is  executed.
The user should respond with the name of the SYP file or <return>  for
no symbols. The debugger will then respond with '+>'.  After  entering
the BEgin  command, the  user may  enter any  of the debugger commands
and proceed to debug the program under test.



  All Information Presented Here is Proprietary to Digital Research

				 41



      When  the  debugger  is  used  in  a recursive environment local
variables may not be displayed  because they are not stored  in static
memory but are on the stack.

      If you link the debugger as  in the sample above, you will  have
two undefined symbols, 1@XOP1 and '@WRL', which are required to  write
real numbers. Because USERPROG does not use reals the real number  run
time package  has not  been linked  causing the  above routines  to be
undefined. This will not, of  course, cause any problems in  execution
as there are no real numbers to display. An attempt to display a  real
will just cause the program to return to the operating system.

2.5.2		COMMAND FORMAT

      The  debugger  converts  items  whenever  possible into the form
expected by  the user  (i.e. decimal  for integers,  TRUE /  FALSE for
booleans, etc.). When this is  not possible the debugger will  display
the data in HEX  and ASCII.  Described  below are the syntax  elements
and the commands.

      The  term  <name>  is  either  a  variable  name,  a   procedure
function  name,  or  a  prefixed  variable  name.  Names  are  1  to 8
characters  long  and  follow  the  syntax  of  the  Pascal  compiler.
Underscores are allowed and ignored  (e.g. A-B is exactly the  same as
AB). A prefixed variable name  is a variable identifier prefixed  with
a procedure  / function  name. This  syntax is  used to  display local
variables and parameters in  non-recursive modules. If two  procedures
each have a local procedure of the same name only the first  procedure
linked will be available for symbolic display.

      The term <num> is either a  decimal number or, if prefixed by  a
1$1  character,  a  hexadecimal  number.  Decimal  numbers fall in the
range 0..32767. Hexadecimal numbers in the range O..FFFF.

<name>		::= <procedure identifier> : <variable identifier> |
		    <variable identifier> |
		    <num>
<num>		::= $ <hex number> |
		    <decimal number>

      The  variable  display  commands  are  followed  by  a parameter
designated  as  <parm>  which  is  defined  in terms of <name>, <num>,
offsets, and an indirection symbol.

	     <parm> ::= [<name> | <num>] {^} {[+ | -] <num>}

The  offset  syntax  is  the  character  '+'  (which is assumed if not
present) or '-' followed  by <num>. The value  of <num> is the  number
of bytes  added to  or subtracted  from the  address obtained thus far
from the <parm>. The indirection symbol, '^', is used with





  All Information Presented Here is Proprietary to Digital Research

				 42




variables which  are pointers.  When used,  the debugger  displays the
data  pointed  to  by  the  pointer,  not  the  content of the pointer
itself. Examples of <parm> are shown below:

(* Pascal declarations: *)

TYPE
    PAOC = ARRAY [l..40] OF CHAR;

VAR
    ABC : INTEGER;
    PTR : ^PAOC;

Example of <parm>:

    ABC		an integer
    PTR		contents of PTR
    PTR^	entire array
    ABC+10	10 bytes past ABC location
    PTR^+10	PTR^[11]
    ABC-3	3 bytes before ABC
    PTR^-3	3 bytes before the array, PAOC
    $3FFD	Absolute location
    $423B^	32 bytes pointed to by $423B
    $3FFD+$5B	32 bytes at $4058
    $423B^+49	32 bytes pointed to by contents
		    of $423B + 49

    PROC1:I	local variable
    PROC2:J^+9	offset from local pointer

      The command used  to alter the  contents of a  memory address is
'SE<parm>'.  This  command  displays  the  byte  at  that  address  in
decimal. A  decimal (or  hex if  the $  is used)  value followed  by a
carriage  return  replaces  the  current  byte  with the new one. If a
number is entered  which is cannot  be contained in  one byte (greater
than 255) then the last two digits are used. The address and  contents
of the next byte of memory is then displayed. Alteration may  continue
until a  '.' followed  by a  carriage return  is entered which returns
you  to  the  command  mode.  This  works  in  the same way as the Set
command in DDT or SID.













  All Information Presented Here is Proprietary to Digital Research

				 43





Command Syntax		Meaning
--------------		-------

DV <name> {^}		Display Variable - variable display by <name>.
			If this  is a  pointer variable,  the contents
			of the  pointer is  displayed unless  followed
			by - which causes  the data pointed to  by the
			pointer to bedisplayed.

The following  commands are  used when  symbols are  not available  or
when fields within records or array elements are to be displayed:

DI <parm>		Display Integer
DC <parm>		Display Character
DL <parm>		Display Logical (Boolean)
DR <parm>		Display Real
DB <parm>		Display Byte
DW <parm>		Display Word
DS <parm>		Display String
DX <parm> {,num}	Display eXtended (structures)
			This is always displayed in HEX/ASCII format
			Num is the size, in bytes, for memory dump.
			The default value is 320 bytes.

The following commands allow control of the user program:

TR or T			Trace - Execute one line and return
T<num>			Trace <num> lines and return
BE			BEgin execution (start program from beginning)
GO			Continue execution from a breakpoint
SB <name>		Set breakpoint at beginning of procedure
			<name>
RB <name>		Remove breakpoint at procedure <name>
E+			Enable display entry and exit of each
			procedure or function during execution
			(default on)
E-			Disable entry / exit display
PN			Display procedure names from SYP file
VN <name>		Display variables associated with procedure
			<name>
SE <parm>		Modify contents of memory at <parm>. A '.'
			terminates this command.
??			HELP! List of commands found in DBUGHELP.TXT.











  All Information Presented Here is Proprietary to Digital Research

				 44




2.6	LIBRARIAN, LIB/MT+
	------------------

      The  Pascal/MT+  librarian  is  a  dual  purpose  program.   Its
primary  purpose  is  to  logically  concatenate ERL files together to
construct a searchable library  such as PASLIB. Its  secondary purpose
is to  convert Pascal/MT+  ERL files  into files  which are compatible
with Microsoft compatible linkers such as L80 and Link80.

2.6.1 INVOCATION AND INPUT FILES

      The librarian is invoked as shown below:

		LIBMT <filename>

      LIB/MT+  operates  using  a  file  of  type '.BLD' as input. The
filename given  when invoking  LIBMT must  not use  the extent, 'BLD'.
This file contains  an output file  name followed by  a list of  input
file names, each name on a separate line. Input files may be a  single
module or a library of modules.  NOTE:  A PASCAL MODULE COMPILED  WITH
THE  'X'  (EXTENDED)  OPTION  (USED  FOR  THE DISASSEMBLER) MAY NOT BE
PROCESSED.

2.6.2		USE AS A LIBRARIAN

      An  example  '.BLD'  file  for  creating  a  LINK/MT+ compatible
library is shown below:

	MYLIB.ERL
	MYMOD1.ERL
	MYMOD2.ERL
	MYMOD3.ERL

When processed  by LIB/MT+  this fill  will cause  the deletion of any
old  copy  of  MYLIB.ERL  and  then  read  and concatenate MYMOD1.ERL,
MYMOD2.ERL  and  MYMOD3.ERL  and  place  the  output  into  MYLIB.ERL.
Pascal/MT+  modules,  libraries,  and  appropriate  assembly  language
modules  are  valid  as  input.  The  extension  on  the files must be
supplied but  need not  be '.ERL'.  The output  file must  be of  type
'.ERL' if it is to be processed by Link/MT+.

      The Link/MT+  linker is  a one  pass linker.  When the IS option
is used  to signify  that a  file is  a library  the linker loads only
those  modules  which  have  been  referenced  by  previous   modules.
Therefore the order  of modules in  your library is  important. If the
modules  are  concatenated  as:   A,B,C  then  modules  B and C cannot
contain references to module A unless they are guaranteed that  module
A is loaded. Module A, however,  can contain references to B and/or  C
because this will cause the linker to load them.





  All Information Presented Here is Proprietary to Digital Research

				 45




      Remember, only entire  modules are extracted  from a library  by
the  linker  and  that  single  procedures  from  a  module  are   not
extracted. All entry points, both code  and data, are used as a  basis
for searching when IS is used.  Only one entry point in a  module need
be referenced to force loading that entire module.

      PASLIB may not  be altered using  this librarian because  of its
special  construction.  Link  the  replacement  modules before linking
PASLIB  to  resolve  references  to  those  routines  before PASLIB is
searched. If the replacement routines are  in a library, it is a  good
idea  NOT  to  search  it  because  the  references to the replacement
routines may not be made until PASLIB is processed.

2.6.3		USE AS A CONVERTER TO L80 FORMAT

      If the first line of the  BLD file contains only 'L80' or  '180'
then the  output file  will be  L80 compatible,  otherwise it  will be
compatible with Link/MT+.  An L80 compatible  file will NOT  work with
Link/MT+. A sample BLD file for  converting a library and / or  module
to L80 format is given below.

	L80
	MYLIB.REL
	MYMOD1.ERL
	MYMOD2.ERL
	MYMOD3.ERL

      LIB/MT+  creates  a  file  called  MYLIB.REL  which contains the
converted  MYMOD1,   MYMOD2,  and   MYMOD3.  The   conversion  process
truncates all public names to  6 characters in length which  may cause
duplicate symbol errors when using L80 which did not occur when  using
Link/MT+  because  Link/MT+  allows  public  names  to  be  up  to   7
characters in length.

The features gained by using this program and L80 are:

	1. The ability to use multiple origins of code and data

	2. The ability to have initialized data in the DSEG

	3. The ability to use COMMON

The features  of the  Pascal/MT+ system  lost when  using this program
and L80 are:

	1. Overlays

	2. The ability to generate a HEX file

	3. The ability to generate a SYM file for using SID

	4. The /D switch of L80 reserves space in memory and


  All Information Presented Here is Proprietary to Digital Research

				 46




	   writes uninitialized data to the disk which may
	   result in a very large COM file

	5. 7 character significance in public names

	6. The disassembler may not be run using a REL file

	7. The /F option (CMD files) may not be used

	8. Programs which link properly with Link/MT+ may
	   not link with L80 because they are too large to
	   fit into memory at link-time (see number 4)

	9. Unlike LINKMT, if you specify /P:4000 when using
	   L80, the area from 100H through 3FFFH will also
	   be saved in the COM file. LINK/MT+ saves the byte
	   destined to be loaded at 4000H as the first byte
	   in the COM file. This has both advantages and
	   disadvantages.

       10. The Pascal feature "temporary" files in which the
           run-time system creates a file name for the user
	   will not operate with L80.

       11. Programs which work with Link/MT+ may suddenly stop
           working with L80 because if the /D switch is not
	   used then all data is initialized to 00 by Link/MT+.
	   Therefore, watch out for uninitialized variables!


























  All Information Presented Here is Proprietary to Digital Research

				 47


























































  All Information Presented Here is Proprietary to Digital Research

				 48





		CHAPTER 3: PASCAL/MT+ LANGUAGE EXTENTIONS
		-----------------------------------------

      The purpose of this chapter is to describe the function and  use
of the Pascal/MT+ extensions to the Pascal language.

  o Section 1 is a description of modular compilation. A sample
    main program and module are listed.

  o Section 2 describes interfacing to assembly language programs.

  o The third section deals with overlays.

  o The built-in procedures and functions are defined with samples
    in Section 4.

  o Section 5 describes chaining.

  o Section 6 talks about interrupt procedures.

  o The seventh section describes nonstandard data access.

  o Imbedded assembly code is discussed in the eighth section.

  o Finally, Section 9 presents details on writing recursive programs.




























  All Information Presented Here is Proprietary to Digital Research

				 49




3.1	MODULAR COMPILATION
	-------------------

      Pascal/MT+  supports  a  flexible  modular  compilation  system.
Unlike other systems  used for Pascal,  such as UNITS,  the Pascal/MT+
system allows an easy transition from large monolithic programming  to
modular programming without a great deal of preplanning. Programs  may
be developed in  a monolithic fashion  until they become  too large to
manage (or  compile) and  then split  into modules  at that  time. The
Pascal/MT+  modular   compilation  system   allows  full   access   to
procedures  and  variables  in  any  module  from  any other module. A
compiler toggle (E+/-) is provided  to allow the user to  "hide", i.e.
make  private,  any  group  of  variables  or procedures.  See Section
2.2.4 for a discussion of the $E toggle.

      The structure of a  module is similar to  that of a program.  It
begins with  the reserved  word MODULE  followed by  an identifier and
semicolon,  e.g.,  MODULE  TEST1;,  and  ends  with  the reserved word
MODEND followed  by a  dot, e.g.,  MODEND. In  between these two lines
the  programmer  may  declare  label,  const, type, var, procedure and
function sections  just as  in a  program. Unlike  a program, however,
there  is  no  BEGIN..END  section  after  the  procedure and function
declarations, just the word MODEND followed by a dot

	Example:

	MODULE MOD1;

	<label, const, type, var declarations>

	<procedure / function declarations and bodies>

	MODEND.

      In order to access variables, procedures and functions in  other
modules (or in  the main program)  a new reserved  word, EXTERNAL, has
been added and is used for two purposes.

      First,  the  word  EXTERNAL  may  be  placed after the colon and
before the type  in a GLOBAL  variable declaration denoting  that this
variable list is not  actually to be allocated  in this module but  is
really  in  another  module.  No  storage  is  allocated for variables
declared in this way.

	Example:

	I,J,K : EXTERNAL INTEGER;	(* in another module *)

	R:	EXTERNAL RECORD		(* again in another module *)
			 ...		(* some fields *)
			END;



  All Information Presented Here is Proprietary to Digital Research

				 50




      The  user   MUST  BE   responsible  for   matching  declarations
identically as  the compiler  and linker  do not  have the  ability to
type check.

      Second,  the  EXTERNAL  word  is  used to declare procedures and
functions  which  exist  in  other  modules.   These declarations must
appear before the  first normal procedure  or function declaration  in
the  module/program.  Externals  may  only  be  declared at the global
(outermost) level of a program or module.

      Just  as  in  variable   declarations,  the  Pascal/MT+   system
requires  that  the  user  make  sure  that  the  number  and  type of
parameters match exactly and that the returned type match exactly  for
functions as the compiler and linker  do not have the ability to  type
check across modules.  External routines may  NOT have procedures  and
functions as parameters.

      The  user  should  note  that  in  Pascal/MT+ external names are
significant only to seven  characters and not eight.  When interfacing
to assembly  language the  user must  limit the  length of identifiers
accessable by assembly language to six characters.

      Listed below are a main program skeleton and a module  skeleton.
The main program  references variables and  subprograms in the  module
and  the  module  references  variables  and  subprograms  in the main
program. The only differences between a main program and a module  are
that at the beginning of a  main program there are 16 bytes  of header
code and a main program body following the procedures and functions.


























  All Information Presented Here is Proprietary to Digital Research

				 51





		Main Program Example:

	PROGRAM EXTERNAL_DEMO;

	<label, constant, type declarations>

	VAR

	   I,J : INTEGER;	(* AVAILABLE IN OTHER MODULES *)

	   K,L : EXTERNAL INTEGER; (* LOCATED ELSEWHERE *)

	EXTERNAL PROCEDURE SORT(VAR Q:LIST; LEN:INTEGER);

	EXTERNAL FUNCTION IOTEST:INTEGER;

	PROCEDURE PROC1;
	BEGIN
	   IF IOTEST = 1 THEN
		(* CALL AN EXTERNAL FUNC NORMALLY *)
	   ...
	END;

	BEGIN
	   SORT(....)
		(* CALL AN EXTERNAL PROC NORMALLY *)
	END.



























  All Information Presented Here is Proprietary to Digital Research

				 52




	Module Example: (Note these are separate files)

MODULE MODULE_DEMO;
< label, const, type declarations>

VAR
   I,J : EXTERNAL INTEGER;	(* USE THOSE FROM MAIN PROGRAM *)
   K,L : INTEGER;		(* DEFINE THESE HERE *)
   EXTERNAL PROCEDURE PROC1;	(* USE THE ONE FROM MAIN PROG *)

   PROCEDURE SORT(...) 		(* DEFINE SORT HERE *)
       ...

   FUNCTION IOTEST:INTEGER;	(* DEFINE IOTEST HERE )*
       ...

   <maybe other procedures and functions here>
MODEND.




































  All Information Presented Here is Proprietary to Digital Research

				 53




3.2	PASCAL/MT+ : ASSEMBLY INTERFACING
	---------------------------------

      This  section  provides  information  for those Pascal/MT+ users
who  wish  to  call  assembly  language  routines  from  a  Pascal/MT+
program.  Included   is  a   list  of   assemblers,  required   naming
conventions,  variable  accessing,  parameter  passing conventions and
restrictions on  what assembly  language features  can be  linked with
LINK/MT+.

3.2.1 	ASSEMBLERS

      The  assemblers  used  with  Pascal/MT+  must  generate the same
relocatable format as the compiler.  The 8080 and Z80 versions  of the
Pascal/MT+  system  generate  Microsoft  compatible relocatable files.
This  format  is  generated  by  the  Microsoft  M80  and  the Digital
Research  RMAC  assemblers.  Both  of  these assemblers have been used
successfully by Digital Research to generate portions of the  run-time
library. LINK/MT+ can handle files generated by compatible  assemblers
within  the  restrictions  of  the  linker,  but other linkers may not
necessarily  be  able  to  link  code  generated  by  the   Pascal/MT+
compiler. See the  description of the  librarian, LIB/MT+, for  making
files compatible with other linkers.

3.2.2	NAMING CONSIDERATIONS

      The assemblers and the  Pascal/MT+ compiler each generate  entry
point and external reference  records in the relocatable  file format.
These  records  contain  external  symbol  names. The Microsoft format
allows for up  to 7 character  names and the  Pascal/MT+ compiler uses
all  7  characters,  but  most  assemblers  only  generate 6 character
names. This means that if a variable is to be located in a  Pascal/MT+
program and accessable  to an assembly  language routine by  name, the
user must limit the name to 6 characters.

      In addition, M80 allows symbols to begin with $ and RMAC  allows
symbols  to  begin  with  ?  neither  of  which  is a legal identifier
character in  Pascal/MT+. M80  also does  not consider  $ to  be a non
significant  character  but  RMAC  does.  This  means  that in M80 the
symbol A$B is actually  placed in the relocatable  file as A$B but  in
RMAC the same symbol would be in  the file as AB. When using RMAC  the
use  of  $  to  simulate  the  underscore  (_)  is  often used but not
transportable to M80.











  All Information Presented Here is Proprietary to Digital Research

				 54





3.2.3	VARIABLE ACCESSING

      Accessing  assembly  language  variables  from Pascal and Pascal
variables from assembly language is very simple.

3.2.3.1	Assembly Language Entry Points from Pascal

      To access  assembly language  variables or  routines from Pascal
they should be declared as PUBLIC in the assembly language module  and
as  EXTERNAL  in  the  Pascal/MT+  program. A sample assembly language
module and  Pascal program  listed at  the end  of this  chapter shows
this feature.

3.2.3.2	Pascal Entry Points From Assembly Language

      To  access  Pascal/MT+  GLOBAL  variables  and  routines from an
assembly language program the user  must declare the name to  be EXTRN
in the assembly  language program and  simply as a  global variable or
routine in the Pascal program (make sure the $E+ toggle is on!)

	EXAMPLE:

		; ASSEMBLY LANGUAGE PROGRAM FRAGMENT

			EXTRN 	PQR
			LXI	H,PQR	;GET ADDR OF PASCAL VARIABLE
			.
			.
			.
			END

		(* PASCAL PROGRAM FRAGMENT *)

		VAR (* IN GLOBALS *)
		  PQR : INTEGER;       (* ACCESSABLE BY ASM ROUTINE *)

3.2.4	DATA ALLOCATION

      In addition  to accessing  the variables  by name  the user must
know how the variables are allocated in memory. Section 5.1  discusses
the storage allocation and format  of each built-in scalar data  type.
Variables  allocated  in  the  GLOBAL  data  area are allocated in the
order  declared.  The  exception  is  that  variables  which are in an
identifier list before a type (e.g. A,B,C : INTEGER) are allocated  in
reverse order (i.e. C first, followed by B, followed by A).  Variables
are  packed  together  in  memory  and  no  space  is left between one
declaration and the next:







  All Information Presented Here is Proprietary to Digital Research

				 55




	EXAMPLE:

		A	: INTEGER;
		B	: CHAR;
		I,J,K	: BYTE;
		L	: INTEGER;

	STORAGE LAYOUT:

		+0 A LSB
		+1 A MSB
		+2 B
		+3 K
		+4 J
		+5 1
		+6 L LSB
		+7 L MSB

      Structured  data  types:  ARRAYs,   RECORDs  and  SETs   require
additional explanation.  ARRAYs are  stored in  ROW major  order. This
means that A: ARRAY [1-3,1-3] OF CHAR stored as:

		+0 A[l,l]
		+1 A[1,2]
		+2 A[1,31

		+3 A[2,11
		+4 A[2,21
		+5 A[2,31

		+6 A[3,11
		+7 A[3,2]
		+8 A[3,31

      This  is  logically  a  one  dimensional  array  of  vectors. In
Pascal/MT+ all  arrays are  logically one  dimensional arrays  of some
other type.

      RECORDs are stored in the same manner as global variables.

      SETs are  always stored  as 32  byte items.  Each element of the
set is stored  as one bit.  SETs are byte  oriented and the  low order
bit of  each byte  is the  first bit  in that  byte of  the set. Shown
below is the set 'A'..'Z':










  All Information Presented Here is Proprietary to Digital Research

				 56





	Byte number

	00 01 02 03 04 05 06 07 08 09 OA OB OC OD OE OF 10 ... 1F
	-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ... --
	00 00 00 00 00 00 00 00 FE FF FF 07 00 00 00 00 00 ... 00

      The first  bit is  bit 65  ($41) and  is found  in byte 8 bit 1.
The  last  bit  is  bit  90  and  is  found  in byte 11 bit 2. In this
discussion bit 0 is the least significant bit in the byte.

3.2.5	PARAMETER PASSING

      When  calling  an  assembly  language  routine  from  Pascal  or
calling  a  Pascal  routine  from  assembly  language,  parameters are
passed on the stack.  Upon entry to the  routine the top of  the stack
contains the  return address.  Underneath the  return address  are the
parameters in  reverse order  from declaration:  (A,B:INTEGER; C:CHAR)
would result in C on top of B on top of A. Each parameter requires  at
least  one  16-bit  WORD  of  stack  space.  A character or boolean is
passed as a 16-bit word with  a high order byte of 00.  VAR parameters
are passed by address. The  address represents the byte of  the actual
variable with the lowest memory address.

      Non-scalar  parameters  (excluding  SETs)  are  always passed by
address. If the parameter is a value parameter then code is  generated
by the compiler  in a Pascal  routine to call  @MVL to move  the data.
SET parameters are passed by value  on the stack and the @SS2  routine
is used  to store  them away.  SETs are  stored on  the stack with the
least significant byte on top  (low address) and the most  significant
byte on bottom (high address).

      The example below shows a  typical parameter list at entry  to a
procedure:

	PROCEDURE DEMO(I,J : INTEGER; VAR Q:STRING; C,D:CHAR);

	AT ENTRY STACK:	+0	RETURN ADDRESS
			+1	RETURN ADDRESS
			+2	D
			+3	BYTE OF 00
			+4	C
			+5	BYTE OF 00
			+6	ADDRESS OF ACTUAL STRING
			+7	ADDRESS OF ACTUAL STRING
			+8	J (LSB)
			+9	J (MSB)
			+10	I (same as J)
			+11	I (same as J)

      The assembly  language program  must remove  all parameters from
the stack before returning to the calling routine.



  All Information Presented Here is Proprietary to Digital Research

				 57




      Function  values  are  returned  on  the  stack. They are placed
logically  underneath  the  return   address  before  the  return   is
executed. They  therefore remain  on the  top of  the stack  after the
calling  program  is  re-entered  after  the return. Assembly language
functions may  only return  the scalar  types INTEGER,  REAL, BOOLEAN,
and CHAR.

      See Section 3.2.7  for a sample  assembly language function  and
Pascal program

3.2.6 	RESTRICTIONS

      The user should  beware of the  following restrictions that  are
placed upon program which are linkable with the Link/MT+ linker:

	a) COMMON is not supported

	c) Use of DB and DW in the DSEG of an assembly language
	   routine is not supported. Use the DB and DW in
	   the CSEG for non-ROM based applications.

	d) Use of the Request Library search feature is not
	   supported by Link/MT+.

3.2.7	ASSEMBLY LANGUAGE INTERFACE EXAMPLE

      A sample assembly language  module and the Pascal  program which
uses  it  are  listed  on  the  following pages. The assembly language
module simulates  the PEEK  and POKE  routines of  BASIC. PEEK returns
the byte found  at the address  passed to it,  and POKE puts  the byte
passed to it at the location pointed to by the address passed to it.























  All Information Presented Here is Proprietary to Digital Research

				 58





      Pascal program  which uses  the PEEK  and POKE  routines in  the
assembly language module listed on the next page.

PROGRAM PEEK_POKE;

TYPE
	BYTEPTR = ^BYTE;

VAR
	ADDRESS : INTEGER;
	CHOICE : INTEGER;
	BBB : BYTE;
	PPP : BYTEPTR;

EXTERNAL PROCEDURE POKE (B.: BYTE; P : BYTEPTR);
EXTERNAL FUNCTION PEEK (P : BYTEPTR) : BYTE;

BEGIN
  REPEAT
    WRITE('Address? (use hex for large numbers)
    READLN(ADDRESS);
    PPP := ADDRESS;	{ONLY ALLOWED IN PASCAL/MT+8080}
    WRITE('l) Peek OR 2) Poke');
    READLN(CHOICE);
    IF CHOICE = 1 THEN
      WRITELN(ADDRESS,' contains ',PEEK(PPP))
    ELSE
      IF CHOICE = 2 THEN
	BEGIN
	  WRITE('Enter byte of data: 1);
	  READLN(BBB);
	  POKE (BBB, PPP)
	END
  UNTIL FALSE
END.



















  All Information Presented Here is Proprietary to Digital Research

				 59




      Assembly  language  module  used  by  PEEK  POKE  program. It is
written  using  8080  mnemonics  and  assembled  using  a  relocatable
assembler.

	PUBLIC PEEK
	PUBLIC POKE

;Peek returns the byte found in the address passed on the stack
;It is declared as an external in a Pascal program as:
;EXTERNAL FUNCTION PEEK(P : BYTEPTR) : BYTE

PEEK:
	POP B	;RETURN ADDRESS INTO BC
	POP H	;POINTER TO BYTE INTO HL
	MOV E,M	;MOVE CONTENTS OF MEMORY POINTED TO BY HL INTO E
	MVI D,O	;PUT A 00 INTO D
	PUSH D	;RETURN FUNCTION VALUE
	PUSH B	;PUT RETURN ADDRESS ON STACK
	RET	;RETURN TO CALLER (NO PARAMETERS LEFT ON STACK)

;Poke places a byte into memory
;It is declared as an external in a Pascal program as:
;EXTERNAL PROCEDURE POKE(B : BYTE; P : BYTEPTR);

POKE:
	POP B	;GET RETURN ADDRESS INTO BC
	POP H	;P, THE BYTE POINTER IS PUT INTO HL
	POP D	;REGISTER E GETS THE BYTE, D GETS THE EXTRA BYTE OF 00

	MOV M,E ;PUT E INTO MEMORY POINTED TO BY HL

	PUSH B	;RETURN ADDRESS ON TOP OF STACK
	RET   	;RETURN TO CALLER (NO PARAMETERS LEFT ON STACK)

	END



















  All Information Presented Here is Proprietary to Digital Research

				 60




3.3	PASCAL/MT+ OVERLAYS
	-------------------

      The overlay system allows users  to write programs which can  be
linked together  such that  when needed,  portions of  the program are
automatically loaded from the disk. With the overlay system,  programs
no longer need  to reside entirely  in memory. Modules  which are less
frequently used  or groups  of modules  which need  not be co resident
may be stored  on the disk  in "overlay groups"  and loaded only  when
called.

      If you are not  an exprienced Pascal/MT+ programmer  we strongly
suggest you start  by writing programs  which do not  use overlays. An
experienced  Pascal/MT+  programmer   is  comfortable  with   EXTERNAL
procedures and  variables, knows  how to  operate the  linker, and  is
familiar with how to find things in the Pascal/MT+ manual.

      The  major  features  of  the  Pascal/MT+  overlay  system   are
summarized below:

	o Up to 255 overlay groups
	o Up to 16 separate overlay areas
	o Overlays may call other overlays
	o Calling of overlays from other overlays in the same area
	o Overlays are loaded from disk only when necessary
	o Overlays may contain an arbitrary number of modules
	o Linkage to a procedure in an overlay is done by name
	o Complete access to root program.procedures, functions
	  and variables (including run-time package routines)
	o User may specify drives containing individual overlays
	  at run-time

3.3.1	DEFINITION OF OVERLAYS

      Below are some  definitions of terms  which are used  frequently
throughout the remaining discussion of overlays.

	1. ROOT program - that portion of the program which
	   always resides in memory and is contained in
	   a COM file. It consists of a main program and the
	   run-time routines from PASLIB required by the main
	   program and optionally the run-time routines required
	   by the overlays.

	2. OVERLAY group- a set of possibly unrelated modules
	   which is linked using a special method (described
	   below) and is contained in a file with a numeric
	   extension. (e.g. PROG.001)

	3. OVERLAY area - an area of memory into which the




  All Information Presented Here is Proprietary to Digital Research

				 61




	   overlay manager will load overlay groups as
	   necessary. Its location and size must be planned
	   by the user and is specified at link-time.

	4. OVERLAY static variables - variables which are
	   global to a module or are local to procedures
	   in a statically compiled module and the module
	   is linked into an overlay. Recursion can reduce
	   the amount of static data, but does not necessarily
	   eliminate it because run-time code linked with
	   the overlay may contain static data.
	   (see the /X switch below).

      The  overlay  system  allows  up  to  255  overlay groups. These
groups  consist  of  one  or  more  modules (either Pascal or assembly
language)  which  contain  procedures  and  functions.  The Pascal/MT+
overlay  system  allows  the  overlay  groups  to contain an arbitrary
number of  entry points  (procedures and  functions) all  of which are
accessable by the  root program and  other overlays. Each  entry point
is individually  accessable by  name. Overlay  procedure and  function
names (as with all externals) are limited to 7 significant  characters
by the linker and relocatable format.

      As the  system distributed,  the overlay  manager in  PASLIB has
space for 50 overlay groups numbered 1 through 50 in its drive  table.
This is done to  save 200 bytes of  space in the run-time  package. If
more  are  needed  the  user  may  modify  the overlay manager source,
re-assemble  it,  and  link  it  before  PASLIB.  Numbering of overlay
groups need not be  consecutive.  If you  desire to use, for  example,
three overlays in three different overlay areas, they may be  numbered
1,17,33  or  any  other  combination  which  places  the overlays into
different areas.

      Overlays  in  the  Pascal/MT+  system  are normally handled in a
single overlay area. More  extensive schemes can be  implemented using
multiple  overlay  areas.  The  overlay  system  supports  up  to   16
different  overlay  areas.  These  areas  work in conjunction with the
overlay  number  to  determine  into  which  area any given overlay is
loaded. If  the address  for an  overlay area  is not  specified it is
assumed to be the  same as overlay area  1. Overlays 1 through  16 are
always loaded into  area number 1,  overlays 17 through  32 are loaded
into area  number 2,  etc. up  through overlays  241 through 255 which
are  loaded  into  area  number  16.  The  user  is  responsible   for
determining the address and size of the overlay areas and making  sure
that modules do not exceed the size of the area into which they  load.
The overlay  loading routine  loads overlays  into memory  in 128 byte
segments so consider  the extra size  when saving space  for overlays.
Area number one must be specified, the remainder are optional.

      A  schematic   diagram  of   the  relationship   of  procedures,
functions, modules and overlays is shown below:



  All Information Presented Here is Proprietary to Digital Research

				 62





    procedure\
    function  |--module--+
    procedure/		 |
			 +------ overlay group 1 ----- .001 file
    procedure\		 |	loaded into area 1
    procedure |--module--+
    procedure/
    function \
    procedure |--module--+
    procedure/		 |
			 +------ overlay group 17 ----- .Oll file
    procedure\		 |	loaded into area 2 if
    procedure |--module--+	address given, otherwise loaded
    procedure/			into area 1.

3.3.2	LINKING OVERLAYS AND ROOT PROGRAMS

      The  directives  to  the  linker  are described in the following
three  sections.  The  switches  are  not  location sensitive. Section
3.3.2.4  gives  instructions  on  linking  root  programs  and Section
3.3.2.5 shows  how to  link an  overlay. The  information contained in
these sections  is summarized  in Section  3.3.2.7, the  list of steps
actually  required  to  link   program  which  uses  overlays.    Some
information may  appear to  be redundant,  but it  is the  hope of the
author that plenty of explanation  will help all users understand  the
overlay scheme.

3.3.2.1 Overlay Area Switch /V

      The  /Vn:mmmm  switch  is  to  inform  the overlay manager where
overlay area (n) is to be located (mmmm). THIS SWITCH IS USED TO  LINK
ROOT PROGRAMS ONLY. Because up to  16 overlay areas may be used,  this
switch may be used  up to 16 times  when linking the main  program. It
must be used at  least once to give  the defualt overlay area  address
for all overlay groups.

      To find what  value to use  for /V, link  the root program  with
PASLIB. If /D  is used then  the root program's  total code size  plus
100H is  the lowest  address which  may be  used for  an overlay  area
address, the parameter to /V. If /D is not used then the parameter  to
/V i s the root program's code size plus its data size plus 100H.

3.3.2.2 Overlay Group and SYM Switch /0

      The /O:n switch instructs the  linker that the previous file  is
a SYM  file which  is to  be entered  into the  linker symbol table as
entry points. The SYM file  is produced when linking the  root program
and contains all of the entry points in the root program.






  All Information Presented Here is Proprietary to Digital Research

				 63






Because of  this symbolic  link to  the root  program, if  a change is
made in  an overlay  only the  overlay must  be re-linked  (unless the
code size or data size  changes beyond the constraints given  when the
root was linked.) The /0 switch  also informs the linker that this  is
overlay group number  "n". This information  is used to  construct the
file name. THIS  SWITCH IS USED  TO LINK OVERLAYS  ONLY. Overlay group
numbers 1 through 16  are part of overlay  area #1. Those numbered  17
through 32 are part of overlay area #2, etc.

3.3.2.3	Overlay Local Storage /X:

      The  /X:nnnn  switch  may  be  used  when  linking  the root and
overlays. When used with the root linking process, the /X:nnnn  switch
informs the  linker how  much space  (nnnn) is  to be  left for  total
local storage  required by  the overlays.  This space  is added to the
value of SYSMEM in @INI so that the base of the heap pointer  (SYSMEM)
will be correct.  The user is  responsible for maintaining  this space
and insuring that it is  sufficient. This is easily done  by examining
the total data size specified at  the end of each overlay link.  If IX
is not specified the overlay static data is located at the top of  the
root data area and the heap cannot be used.

      The  /X:nnnn  switch,  when  used  to link overlays, informs the
linker the offset  from the end  of the root  data area at  which this
particular overlay's  static data  is to  begin. For  example, if  the
total amount  of data  required by  two overlays  in a  program is 500
bytes, and overlay  #1 uses 350  of those bytes,  overlay #1 would  be
linked  with  /X:0000  (or  may  be  omitted)  and overlay #2 would be
linked with /X:015E. The root would be linked with /X:OlF4.

      Give yourself some  extra space when  using this switch  so that
you do not have to re-link everything when the size of the data  areas
change. To find the  amount of data used  by an overlay, link  it once
and note the total data size put out by the linker.

3.3.2.4 Linking Main Program

To link a main program:

LINKMT ROOT,<other root modules> .... PASLIB/S/Vn:mmmm/D:oooo/X:pppp

(note: specifying /V automatically turns /E and /W on,
thereby generating a SYM file)

n    - is a hex	number	1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10
mmmm - is a hex	number	O..FFFF
oooo - is a hex	number	O..FFFF
pppp - is a hex	number 	O..FFFF




  All Information Presented Here is Proprietary to Digital Research

				 64




      This creates the files  ROOT.COM and ROOT.SYM. ROOT.SYM  will be
used in subsequent linking of overlays. It is necessary to use the  /D
switch  when  linking  root  programs   to  be  used  in  an   overlay
environment. The structure of an overlay environment must be as  shown
below:

(low memory)						(high memory)
+--------------+-----------------+-----------+---------------+-------+
|	       |		 |	     |	overlay data.|	     |
| Root program | overlay area(s) | root data | use this size |  heap |
|	       |		 |	     | in /X	     |	     |
+--------------+-----------------+-----------+---------------+-------+
	       ^ specified	 ^ specified		     ^ implied
		 by /V switch	   by /D switch		       by /X

The overlay areas must be located below the root data if you want  the
heap (i.e. NEW and DISPOSE) to operate properly. The parameter to  the
/D switch  must include  the size  of the  root program  and the total
size of the  overlay areas. Leave  some extra room  during development
as the size  of the overlay  areas often changes.  Also, remember that
the loading routine  reads overlays into  memory in 128  byte sectors.
This means that  the total code  size of an  overlay which the  linker
displays usually  is not  the total  amount of  space required by that
overlay in memory.

      The  /X  switch  (when  linking  the main program) specifies the
size of the static space used by the overlays and thereby defines  the
lowest bound of the  heap. It must be  used when the program  requires
the heap. If  it is not  specified, the overlay  data is automatically
placed at the end of the root data by the linker.

3.3.2.5 Linking an Overlay

      Linking an overlay involves reading the SYM file created  during
the linking  of the  root program,  reading the  modules which make up
the overlay, and scanning PASLIB.  The /P:nnnn switch must be  used to
inform the linker  where to start  the code address  for this overlay.
The overlay groups in  area one would all  use the same /P  parameter.
The overlay groups  in area two  would all use  the same /P  parameter
which  is  different  than  that  used  for  area one, unless only one
overlay area is specified in the root program. See the example below.

      The /O:n switch must be used to name the SYM file and  associate
a number with this overlay.

      If the overlay  has any static  data the /Xtnnnn  switch must be
used to inform the linker  that this overlay's data begins  nnnn bytes
after the end of the root program's data area. If it is not used  then
every overlay's data area begins  in the same place, SYSMEM  +2, which
causes all of the data areas to begin just above the root




  All Information Presented Here is Proprietary to Digital Research

				 65




program's data area.

      As  noted,  any  run-time  library  routines located in the root
program  are  not  duplicated  in  the  overlay  file.  This  can save
signficant disk space for  programs which were previously  constructed
via chaining.

	   LINKMT ROOT=ROOT/0:2,MOD1,MOD2,...,PASLIB/S/P:4000
	   (note: overlay's data area is automatically set to
	   the value SYSMEM+2 as found in the symbol file)

      This would  create ROOT.002  containing all  the procedures  and
functions  located  in  MOD1.ERL  and  MOD2.ERL (and any other modules
represented by '-').   If 'ROOT=' is not  present then the overlay  is
named MOD1.002 and cannot be  found by the overlay manager.  All entry
points (procedures  and functions)  are available  for use  by calling
programs. Note that use of  the $E compiler toggle also  allows hiding
procedures  and  functions  from  the  overlay  name  table as well as
eliminating entry point records.

      Root programs (the always  resident portion of the  program) and
overlays (the  mainly disk  resident portion)  are linked  in separate
operations.  Unlike  other  schemes  (notably  the  one  from  Digital
Research used with PL/I-80) the  Pascal/MT+ system allows the user  to
modify an overlay and re-link the overlay only without re-linking  the
entire root program and all overlays. If the root program is  modified
all modules (root and overlays) must be linked. Since linkage  between
the root and an overlay (and between one overlay and another) is  done
symbolically this complete relinkage  is only necessary when  the root
changes.

3.3.2.6 Overlay Filenames

      The basic  file name  for the  overlay must  be the  same as the
root program. The extension  signifies the overlay group  number (e.g.
if the root program  is called XYZ.COM then  the overlay group 1  file
would be called XYZ.001). The extension always begins with 0 and  then
the overlay group  number in hexadecimal  (e.g. overlay 15  is in file
????????.OOF).

3.3.2.7 Linking a Program with Overlays

      The steps  required to  link a  program which  uses overlays are
described in this section.










  All Information Presented Here is Proprietary to Digital Research

				 66





1)	First Link of Root Program

      At this point you do not know the amount of overlay static  data
for the /X switch or  the values to give to  /V or /D. The purpose  of
this  link  is  to  generate  a  SYM  file to be used when linking the
overlays and to find  out the code and  data size of the  root program
when  it  is  linked  with  all  of  the run-time support routines. To
generate the SYM file use a dummy  value for /V or use /E/W. Save  the
code and data size for future reference.

2)	Link First Overlay

      Use the  SYM file  produced in  step 1)  via the  /0 switch. The
overlay group number is up to your choice. If this is to be the  first
overlay  in  the  first  overlay  area,  the  /X  switch  need  not be
specified since the  offset from the  root data is  0. However, it  is
useful to  save a  few bytes  here so  that the  root data has room to
change during development.  For the parameter  to /P use  the starting
address required by all overlays in  this overlay area. It must be  at
least the  total code  of the  root +  100 hex  (because programs  are
loaded  at  100H)  +  some  extra  space for changing code size during
development.  Save  the  total  code  size  and  data  size for future
reference.

3)	Link Second Overlay

      Use the  SYM file  produced in  step 1)  via the  /0 switch. The
overlay group number is  up to your choice,  but it is different  than
that chosen  in step  2). The  value to  use for  /X is  the data size
obtained in step 2) plus some extra for changing sizes. The  parameter
to /P is the  address of the overlay  area with which this  overlay is
associated. It  may or  may not  be the  same as  in step 2). Save the
total size and data size for this overlav.

4)	Link Remaining Overlays

      Link any remaining overlays totaling the overlay data size  from
previous overlay links to use  as the /X parameter. Link  all overlays
in the same  overlay area using  the same parameter  to /P. Then  link
the overlays in the next overlay area using the code size of the  root
plus the code  size of previous  overlay areas plus  some extra space.
The extra space is suggested for program development and necessary  to
fill out  the final  sector because  the overlay  manager reads in 128
bvtes of code at one time.

51	Re-link Root Proaram

      Now you have all of the data necessary to link the root  program
for the final  time. For the  /D parameter use  the overlay area  with
the highest address  + the code  size of the  largest overlay in  that
overlav area. Again, add extra space to fill out the final 128 bvte



  All Information Presented Here is Proprietary to Digital Research

				 67




sector. The /V parameters depend  on how many different overlay  areas
there are  and whether  they start  at different  code addresses. Each
different value  for /P  in an  overlay must  have a  /Vn in  the root
program.  Remember  the  n  on  Vn  is  the  overlay  area number. The
parameter to /X  is the sum  of all of  the overlay data  sizes in all
overlay areas.

6)	Re-link Overlays

      Anytime  the  SYM  file  changes,  all  of  the overlays must be
linked  again.  Because  the  /D  switch  did  not  have  the  correct
parameter in step 1)  , it most likely  changed in step 5)  so the SYM
file changes.

3.3.3	OVERLAY OPERATIONAL DESCRIPTION

3.3.3.1 Declaring an Overlay Procedure

      The Pascal/MT+  compiler accepts  an extended  form of  external
declarations as follows:

EXTERNAL { [ <id> | <intconst> ] } PROCEDURE/FUNCTION ...

The  braces  indicate  that  the   "overlay"  form  of  the   EXTERNAL
procedure/function  declaration  is  optional.  The  "normal"  form is
still  syntactically  and   semantically  correct  for   non-overlayed
programs. The  id/intconst must  be a  constant or  literal number  of
type INTEGER  and specifies  an, overlay  group which  is known to the
overlay manager.

3.3.3.2	Calling an Overlay Procedure

      The compiler will generate a call to @OVL, the overlay  manager,
when each procedure and/or function declared as part of an overlay  is
called. The  overlay group  number and  the character  string for  the
procedure  name  are  passed  to  @OVL  by  the  compiler. The overlay
manager will  then insure  that the  requested overlay  is in  memory,
loading it from  disk only if  it is not  in the desired  overlay area
when the call is made. The overlay manager will then search the  entry
point  table  of  the  overlay  for  the  name  and  call  the address
specified in the  entry point table.  When the called  routine returns
the overlay manager will return  to the calling procedure as  required
if the  calling procedure  is in  the root  program or  in a different
overlay area.

      Care must be taken if the calling procedure is in an overlay  to
insure that it is  reloaded after the call  and that its data  has not
been altered by the called overlay (Section 3.3.3.3).






  All Information Presented Here is Proprietary to Digital Research

				 68



      The user may call a  special routine ROVS) to specify  the drive
on which  to look  for each  overlay. Calls  to the  @OVS routine  may
occur  at  any  time  and  pass  the  overlay number and the requested
drive. @OVS is usually called just prior to the call to the  procedure
which is in an overlay on a different drive. To call the @OVS  routine
declare it as an external procedure as shown below:

	EXTERNAL PROCEDURE @OVS(overlay_number:INTEGER; drive:CHAR);

The drive is specified in character  form (upper case only) and is  in
the  range  '@'..'0'.   The  character  '@'  is  used  to refer to the
currently  logged-in  drive  and  'A'  ..  '0' represent the allowable
disks  in  a  fully  configured  CP/M  environment.  It  is the user's
responsibility to insure that the drive is on-line.

3.3.3.3 Overlays Calling Other Overlays

      If the  overlay manager  is in  the default  non-reload mode, it
does not  reload the  previous overlay  when returing  from an overlay
call, thereby preventing  calling from one  overlay to another  in the
same overlay  area. This  non-reload mode  can be  considerably faster
because it  eliminates unneeded  disk accessing.  The source  code for
the overlay manager  contains an equate  'RELOAD' which may  be set to
TRUE to cause the overlay manager to reload the previous overlay  when
returning  from  an  overlay  call.  The distribution disks contain an
assembled file called ROVLMGR.ERL in which the RELOAD switch has  been
set to  TRUE. To  be able  to use  this reloading  form of the overlay
manager,  ROVLMGR.ERL  may  be  linked  before  the  run-time library,
PASLIB.

      Overlays may  call other  overlays if  the following  conditions
are met:

	1) If any static variables are used in the calling overlay
	   and one or more procedures in the calling sequence use
	   overlay static variables, the /X switch must be used when
	   linking these overlays. This insures that no procedure in
	   the sequence has its data altered by another procedure in
	   the sequence.

	2) If a procedure is calling procedures which are in the
	   same overlay area, the RELOAD switch must be on so that
	   the calling overlay is reloaded. If the called routine is
	   in another overlay area, the RELOAD switch need not be
	   TRUE because the calling procedure is still resident in
	   its overlay area.

      Pascal/MT+  programs  are  always  pure  code  but  user modules
written in assembly language may not be. Be sure to be aware of  using
'IDB" in the code segment  for variables which are really  modified as
they will not be initialized every time the overlay is called  because
the overlay is not reloaded if  the overlay is already in the  overlay
area.

3.3.3.4 Access to Root Program Symbols

  All Information Presented Here is Proprietary to Digital Research

				 69





      Procedures, functions, variables, and run-time routines  located
in the root  program may be  accessed in overlays  via simple external
declarations.

      The user  should note  that run-time  routines used  by the root
are not duplicated in the overlays. Only run-time modules used by  the
individual overlays are stored on the disk in the overlay files.  This
may mean that  to conserve space  the user may  wish to cause  certain
run time  modules (such  as file  input/output) to  be loaded with the
root program even if  not used by the  root program. This may  be done
by  declaring  these  routines  as  external  and  then using the ADDR
function to to cause a reference to be made in the relocata:ble  file.
Using ADDR to  create a reference  to a run-time  routine is necessary
because declaration  of a  routine as  EXTERNAL is  not sufficient  to
cause loading from  PASLIB. Assign a  dummy integer the  result of the
ADDR  function  (you  need  not  even  execute  the  code  to have the
compiler generate the reference). An example follows:

	EXTERNAL PROCEDURE @RIN;
	PROCEDURE X;
	VAR P : ^INTEGER;
	BEGIN
		P := ADDR(@RIN); .... {causes @RIN to be loaded}

3.3.4 	ERROR MESSAGES

      The  overlay  manager  may  encounter  two  errors which it will
write to the screen. The first  is that it cannot find a  procedure or
function within the overlay that  the compiler asked it to  load. This
may  be  due  to  an  incorrect  EXTERNAL  statement or a mis-numbered
overlay.

      The second  error is  that the  manager cannot  find the overlay
requested.  This  means  the  overlay  is  not on the default disk. If
necessary, a call  to @OVS may  be placed in  the program to  tell the
manager where to look for the overlay.

3.3.5	EXAMPLE

      Now for a  simple example. Let  us assume that  you have a  root
program which asks  for a character  from the keyboard  and then calls
one of two  procedures depending upon  the character input.  This is a
simplified example  of a  menu driven  business package.  Let us  also
assume that in the future  you anticipate that the procedures  you are
calling will  become very  large and  that you  will not  have room in
memory for both procedures at the same time. (a good reason for  using
overlays). These  sample compilations  (one program  and two  modules)
are are supplied  on the distribution  disk. We strongly  suggest that
you compile and  link these (as  shown below) and  obtain some feeling
for the operation of the whole overlay package.




  All Information Presented Here is Proprietary to Digital Research

				 70




First the main program:

PROGRAM DEMO_PROG;

VAR
  I : INTEGER;	(* TO BE ACCESSED BY THE OVERLAYS *)
  CH: CHAR;

EXTERNAL [1] PROCEDURE OVL1;	(* COULD HAVE HAD PARAMETERS *)

EXTERNAL [21 PROCEDURE OVL2;	(* ALSO COULD HAVE HAD PARAMETERS *)

(* EITHER COULD ALSO HAVE BEEN A FUNCTION IF DESIRED *)

BEGIN
  REPEAT
    WRITE('Enter character, A/B/Q:
    READ(CH);
    CASE CH OF
      'A','a' : BEGIN
		  I := 1;	(* TO DEMONSTRATE ACCESS OF GLOBALS *)
		  OVL1		(* FROM AN OVERLAY *)
	        END;
      'B','b' : BEGIN
		  I := 2;
		  OVL2
	        END
    ELSE
      IF NOT(CH IN ['Q','q']) THEN
        WRITELN('Enter only A or B')
    END (* CASE *)
  UNTIL CH IN ['Q','q'];
  WRITELN('End of program')
END.




















  All Information Presented Here is Proprietary to Digital Research

				 71





Overlay #1:

MODULE OVERLAY1;

VAR
  I : EXTERNAL INTEGER; (* LOCATED IN THE ROOT *)

PROCEDURE OVLl; (* ONE OF POSSIBLY MANY PROCEDURES IN THIS MODULE *)
BEGIN
  WRITELN('In overlay 1, I=',I)
END;

MODEND.





Overlay #2:

MODULE OVERLAY2;

VAR
  I : EXTERNAL INTEGER; (* LOCATED IN THE ROOT *)

PROCEDURE OVL2; (* ONE OF POSSIBLY MANY PROCEDURES IN THIS MODULE *)
BEGIN
  WRITELN('In overlay 2, I=',I)
END;

MODEND.























  All Information Presented Here is Proprietary to Digital Research

				 72




      After  you  have  compiled  these three modules (PROG,MOD1,MOD2)
you must link them together.

      To link the main program:

  LINKMT PROG,PASLIB/S/D:8000/Vl:4000/X:40

	o  data at 8000 (arbitrary)
	o  overlay areas (1..16) at 4000 (again arbitrary)
	o  64 bytes of extra space

      This will create PROG.COM and PROG.SYM.

      Now to link overlay #1:

  LINKMT PROG=PROG/O:1,MOD1,PASLIB/S/P:4000/L

	o  /0:1 signifies to read PROG.SYM and that this is overlay #1
	o  4000 is the address of the overlay area for this overlay
	o  PASLIB is searched to load only those modules required by
	   this overlay but not present in PROG.COM (see what /L produces)

      This will create PROG.001

      And finally to link overlay #2:

  LINKMT PROG=PROG/0:2,MOD2,PASLIB/S/P:4000/L

(as above but overlay 2)

      Because no local data is used, /X is not specified when  linking
the overlays. The /X  switch is given when  linking the root so  there
is space if  the overlays ever  do add local  data. Also, because  the
overlays do not  call each other,  RELOAD does not  need to be  set to
TRUE.

      When Procedure  OVLl is  called, PROG.001  is loaded  at address
$4000, the  entry point  table is  scanned, and  OVL1 is  called. Upon
completion of OVL1 control is  returned to the root program.  The same
sequence of events occurs for calling OVL2.

      Now, execute the program and  notice that if you enter  the same
letter more than once  in succession (e.g. A,  A, A) that the  overlay
is not  reloaded but  when you  enter the  letters in  alternate order
(e.g. A, B, A, ...) that the overlays are loaded for each call.









  All Information Presented Here is Proprietary to Digital Research

				 73




3.4	BUILT-IN PROCEDURES AND FUNCTIONS
	---------------------------------

      This section  provides descriptions  and examples  of Pascal/MT+
built-in  procedures   and  functions.   Each  routine   is  described
syntactically  followed  by  a  description  of  the parameters and an
example  program  using  the  procedure  or  function.  Section 3.4.29
provides a quick reference summary of all the built-in procedures  and
functions.













































  All Information Presented Here is Proprietary to Digital Research

				 74


























































  All Information Presented Here is Proprietary to Digital Research

				 75





3.4.1		MOVE,MOVERIGHT, MOVELEFT

PROCEDURE MOVE	   (SOURCE, DESTINATION, NUM-BYTES)
PROCEDURE MOVELEFT (SOURCE, DESTINATION, NUM-BYTES)
PROCEDURE MOVERIGHT(SOURCE, DESTINATION, NUM-BYTES)

      These  procedures  move  the   number  of  bytes  contained   in
NUM-BYTES from the location named  in SOURCE to the location named  in
DESTINATION.  MOVELEFT moves  from the left  end of the  source to the
left  end  of  the  destination.  MOVE  is  a  synonym  for  MOVELEFT.
MOVERIGHT moves from the right end  of the source to the right  end of
the destination (the parameters  passed to MOVERIGHT specify  the left
hand end of the source and destination).

      The source and destination may be any type of variable and  both
need not be of the same type. These may also be pointers to  variables
or  integers  used  as  pointers.  They  may  not  be named or literal
constants. The number of bytes is an integer expression between 0  and
64K.

      Watch out for these problems: 1) Since no checking is  performed
as to  whether the  number of  bytes is  greater than  the size of the
destination,  spilling  over  into  the  data  storage adjacent to the
destination will occur if the destination is not large enough to  hold
the number  of bytes;  2) Moving  0 bytes  moves nothing;  3) No  type
checking is done; 'Along with freedom comes responsibility'.

      MOVELEFT and MOVERIGHT are used to transfer bytes from one  data
structure  to  another  or  to  move  data around within a single data
structure. The  move is  done on  a byte  level so  the data structure
type is ignored.  MOVERIGHT is useful  for transfering bytes  from the
low end  of an  array to  the high  end. Without  this procedure a FOR
loop would be required to pick up each character and put it down at  a
higher  address.  MOVERIGHT  is  also  much, much faster. MOVERIGHT is
ideal to use in an insert  character routine whose purpose is to  make
room for characters in a buffer.

      MOVELEFT  is  useful  for  transferring  bytes from one array to
another, deleting characters  from a buffer,  or moving the  values in
one data structure to another.













  All Information Presented Here is Proprietary to Digital Research

				 76




EXAMPLE:

PROCEDURE MOVE-DEMO;
CONST
  STRINGSZ = 80;
VAR
  BUFFER : STRING [STRINGSZ
  LINE : STRING;

PROCEDURE INSRT(VAR DEST : STRING; INDEX : INTEGER; VAR SOURCE:	STRING);
BEGIN
  IF LENGTH(SOURCE) <= STRINGSZ - LENGTH(DEST) THEN
    BEGIN
      MOVERIGHT(DEST[ INDEX ], DEST[ INDEX+LENGTH(SOURCE)
    		LENGTH(DEST)-INDEX+1);
      MOVELEFT(SOURCE[l], DEST[INDEXI, LENGTH(SOURCE));
      DEST[O] :=CHR(ORD(DEST[O]) + LENGTH(SOURCE))
    END;
END;

BEGIN
  WRITELN(-MOVE-DEMO
  BUFFER := 'Judy J. Smith/ 335 Drive/ Lovely, Ca. 95666';
  WRITELN(BUFFER);
  LINE := 'Roland ';
  INSRT(BUFFER, POS(15',BUFFER)+2,LINE);
  WRITELN(BUFFER);
END;

THE OUTPUT FROM THIS PROCEDURE:

MOVE-DEMO
Judy J. Smith/ 355 Drive/ Lovely, Ca.95666
Judy J. Smith/	355 Roland Drive/ Lovely, Ca.95666




















  All Information Presented Here is Proprietary to Digital Research

				 77




3.4.2 	EXIT

PROCEDURE EXIT;

      Procedure EXIT will exit the current procedure/function or  main
program. EXIT will  also load the  registers and re-enable  interrupts
before exiting if EXIT is used in an INTERRUPT procedure. EXIT is  the
equivalent of the RETURN statement in FORTRAN or BASIC. It is  usually
executed as a statement following a test.

	EXAMPLE:

PROCEDURE EXITTEST;
(* EXIT THE CURRENT FUNCTION OR MAIN PROGRAM. *)

PROCEDURE EXITPROC(BOOL : BOOLEAN);
BEGIN
  IF BOOL THEN
    BEGIN
      WRITELN('EXITING EXITPROC');
      EXIT;
    END;
  WRITELN('STILL IN EXITPROC, ABOUT TO LEAVE NORMALLY');
END;

BEGIN
  WRITELN('EXITTEST.....');
  EXITPROC (TRUE) ;
  WRITELN('IN EXITTEST AFTER 1ST CALL TO EXITPROC');
  EXITPROC(FALSE);
  WRITELN('IN EXITTEST AFTER 2ND CALL TO EXITPROC');
  EXIT;
  WRITELN('THIS LINE WILL NEVER BE PRINTED');
END;

Output:

EXITTEST .....
EXITING EXITPROC
IN EXITTEST AFTER 1ST CALL TO EXITPROC
STILL IN EXITPROC, ABOUT TO LEAVE NORMALLY
IN EXITTEST AFTER 2ND CALL TO EXITPROC












  All Information Presented Here is Proprietary to Digital Research

				 78




3.4.3 	@CMD

FUNCTION  @CMD : POINTER TO STRING;

      @CMD  allows  the  user  to  access  the command tail of command
line. This function  retrieves the information  from the command  line
located at hex 80 in CP/M-80, and  moves it to a string. It returns  a
pointer to  this string.  In CP/M-80  the command  tail starts  with a
blank.  This  function  was   designed  to  allow  portability   among
operating systems  which use  a wide  variety of  schemes at the lower
levels  to  implement  this  type  of  parameter passing. @CMD must be
called only  once at  the beginning  of the  program before  any files
have been opened.

	EXAMPLE

PROGRAM @CMD_DEMO;
TYPE
  PSTRG = ^STRING;

VAR S : STRING[16];
    PTR : PSTRG;
    F : FILE OF INTEGER;

EXTERNAL FUNCTION @CMD : PSTRG;

BEGIN
  PTR := @CMD;
  S := PW;
  ASSIGN(F,S);
  RESET(F);
END.






















  All Information Presented Here is Proprietary to Digital Research

				 79




3.4.4	TSTBIT, SETBIT, CLRBIT

FUNCTION  TSTBIT(    BASIC_VAR, BIT_NUM) : BOOLEAN;
PROCEDURE SETBIT(VAR BASIC_VAR, BIT_NUM);
PROCEDURE CLRBIT(VAR BASIC_VAR, BIT_NUM);

      BASIC_VAR is  any 8 or  16 bit variable  such as  integer, char,
byte, word, or boolean. BIT_NUM is  0..15 with bit 0 on the  right. If
BIT  NUM  is  out  of  range  results  are unpredictable but execution
continues. Attempting  to set  bit 10  of an  8 bit  variable does not
cause an error but has no effect on the end result.

      TSTBIT returns TRUE  if the designated  bit in the  basic var is
on, and returns FALSE  if the bit is  off. SETBIT sets the  designated
bit  in  the  parameter.   CLRBIT  clears  the  designated  bit in the
parameter.

      These  procedures  are  useful  for  generating  wait  loops  or
altering  incoming  data  by  flipping  a  bit  where  needed. Another
application is in manipulating a bit mappped screen.

EXAMPLE:

PROCEDURE TST_SET_CLR_BITS;

VAR
  I : INTEGER;
BEGIN
  WRITELN('TST_SET_CLR_BITS.......');
  I := 0;
  SETBIT(I,5);
  IF I = 32 THEN
    IF TSTBIT(I,5) THEN
      WRITELN('I=',I);
  CLRBIT(I,5);
  IF I = 0 THEN
    IF NOT (TSTBIT(I,5)) THEN
      WRITELN('I=',I);
end;

Output:
TST SET CLR BITS .......
I=3
I=O










  All Information Presented Here is Proprietary to Digital Research

				 80





3.4.5	SHR, SHL

FUNCTION SHR(BASIC_VAR, NUM) : INTEGER;
FUNCTION SHL(BASIC_VAR, NUM) : INTEGER;

      BASIC_VAR  is  an  8  or  16  bit  variable.  NUM  is an integer
expression.  SHR  shifts  the  BASIC  VAR  by  NUM  bits  to the right
inserting 0 bits.  SHL shifts the  BASIC_VAR by NUM  bits to the  left
inserting 0 bits.

      The uses  of SHR  and SHL  are generally  obvious. Suppose  a 10
bit value is to be obtained from two separate input ports. Use SHL  to
read them in:

	X := SHL(INP[8] & $1F, 3) ! (INP[9] & $1F);

      The above example reads from port # 8, masks out the three  high
bits returned from  the INP array,  and shifts the  result left. Next,
this result is logically OR'd with  the input from port # 9  which has
also been masked.

      The  following  procedure  demonstrates  the  expected result of
executing these two functions.

	EXAMPLE:

PROCEDURE SHIFT_DEMO;
VAR I : INTEGER;
BEGIN
  WRITELN('SHIFT_DEMO........');
  I := 4;
  WRITELN('I=',I);
  WRITELN('SHR(I,2)=',SHR(I,2));
  WRITELN('SHL(I,4)=',SHL(I,4));
end;

Output:
SHIFT DEMO ........
I=4
SHR(I,2)=l
SHL(I,4)=64













  All Information Presented Here is Proprietary to Digital Research

				 81




3.4.6	HI, LO, SWAP

FUNCTION   HI(BASIC_VAR) : INTEGER;
FUNCTION   LO(BASIC_VAR) : INTEGER;
FUNCTION SWAP(BASIC_VAR) : INTEGER;

      HI returns  the upper  8 bits  of BASIC  - VAR  (an 8  or 16 bit
variable) in the lower  8 bits of the  result. LO returns the  lower 8
bits with the upper  8 bits forced to  zero. SWAP returns the  upper 8
bits of basic var in  the lower 8 bits of  the result and the lower  8
bits of basic var in the upper 8 bits of the result. Passing an 8  bit
variable To  HI causes  the result  to be  0 and  passing 8 bits to LO
does nothing.

      The following example shows  what the expected results  of these
functions should be:

	EXAMPLE:

PROCEDURE HI_LO_SWAP;
VAR
  HL : INTEGER;
BEGIN
  WRITELN('HI_LO_SWAP ........');
  HL := $104;
  WRITELN('HL=',HL);
  IF HI(HL) = 1 THEN
    WRITELN ('HI(HL) =' , HI(HL)
  IF LO(HL) = 4 THEN
    WRITELN('LO(HL)=',LO(HL));
  IF SWAP(HL) = $0401 THEN
    WRITELN('SWAP(HL)=',SWAP(HL));
END;

Output:
HI_LO_SWAP .......
HL=260
HI(HL)=l
LO(HL)=4
SWAP (HL) = 1025














  All Information Presented Here is Proprietary to Digital Research

				 82



3.4.7 	ADDR

FUNCTION ADDR(VARIABLE REFERENCE) : INTEGER;

      ADDR returns  the address  of the  variable referenced. Variable
reference  includes  procedure/function  names,  subscripted variables
and  record  fields.  Externals  may  be  referenced,  including those
located in overlays.  The referenced item  has to be  visible, e.g., a
procedure at lex level 3 is  not visible at the main program  level so
trying  to  find  it's  address  is  not possible. It does not include
named  constants,  user  defined  types,  or  any  item which does not
occupy code or data space.

      This  function  is  used  to  return  the  address  of anything:
compile  time  tables  generated  by  INLINE,  the  address  of a data
structure  to  be  used  in  a  move statement, etc. When recursion is
turned on ADDR does not  return the beginning of the  INLINE generated
constant  table  because  six  bytes  of  code  are  generated  at the
beginning of the procedure. This is  reduced to five bytes when $Q  is
nn

	EXAMPLE:

PROCEDURE ADDR_DEMO(PARAM : INTEGER)
VAR
  REC : RECORD
	  J : INTEGER;
	  BOOL : BOOLEAN;
	END;

  ADDRESS : INTEGER:
  R : REAL;
  Sl : 	ARRAY[l..10] OF CHAR;

BEGIN
  WRITELN('ADDR DEMO ......');
  WRITELN('ADDR(ADDR DEMO)=',ADDR(ADDR DEMO));
  WRITELN('ADDR(PARAR)=',ADDR(PARAM));
  WRITELN('ADDR(REC)=',ADDR(REC));
  WRITELN('ADDR(REC.J) 1, ADDR(REC.J));
  WRITELN('ADDR(ADDRESS)=',ADDR(ADDRESS));
  WRITELN('ADDR(R)=',ADDR(R));
  WRITELN('ADDR(Sl)=',ADDR(Sl));
end;

Output is system dependent









  All Information Presented Here is Proprietary to Diqital Research

				 83




3.4.8	SIZEOF

FUNCTION SIZEOF(VARIABLE OR TYPE NAME) : INTEGER;

      Parameter may be any  variable:  character, array,  record, etc,
or any user defined  type. It is a  compile-time function so only  the
size of items  which do not  generate code to  calculate their address
may  be  a  parameter  to  SIZEOF.  SIZEOF  returns  the  size  of the
parameter in bytes. It  is used in move  statements for the number  of
bytes to be moved.  With SIZEOF the programmer  does not need to  keep
changing constants as the program evolves:

	EXAMPLE:

PROCEDURE SIZE_DEMO;
VAR
B : ARRAY[l..10] OF CHAR;
A : ARRAY[l..15] OF CHAR;
BEGIN
  WRITELN('SIZE_DEMO.......');
  A := '***************';
  B := '0123456789';
  WRITELN('SIZEOF(A)=',SIZEOF(A),' SIZEOF(B)=',SIZEOF(B));
  MOVE(B,A,SIZEOF(B));
  WRITELN('A= ',A);
end;

Output:

SIZEOF(A)=15 SIZEOF(B)=10
0123456789*****























  All Information Presented Here is Proprietary to Digital Research

				 84




3.4.9	FILLCHAR

PROCEDURE FILLCHAR( DESTINATION, LENGTH, CHARACTER);

      DESTINATION  is  a  packed  array  of  characters.  It  may   be
subscripted. LENGTH  is an  integer expression.  If LENGTH  is greater
than the length of DESTINATION, adjacent code or data is  overwritten.
Also,  if  it  is  negative,  adjacent  memory  can  be   overwritten.
CHARACTER is a literal or variable of type char. Fill the  DESTINATION
(a  packed  array  of  characters)  with  the  number  of   CHARACTERs
specified by LENGTH.

      The purpose,of FILLCHAR is to  provide a fast method of  filling
in large data  structures with the  same data. For  instance, blanking
out buffers is done with FILLCHAR.

	EXAMPLE:

PROCEDURE FILL_DEMO;
VAR
  BUFFER : PACKED ARRAY[l..256] OF CHAR;
BEGIN
  FILLCHAR(BUFFER,256,' ');	{BLANK THE BUFFER}
END;






























  All Information Presented Here is Proprietary to Digital Research

				 85





3.4.10	LENGTH

FUNCTION LENGTH( STRING) : INTEGER;

      Returns the integer value of the length of the string.

	EXAMPLE:

PROCEDURE LENGTH_DEMO;
VAR
  Sl : 	STRING[40];
BEGIN
  Sl := 'This string is 33 characters long';
  WRITELN('LENGTH OF ',Sl,'=',LENGTH(Sl));
  WRITELN('LENGTH OF EMPTY STRING = ',LENGTH(''));
end;

Output:

LENGTH OF This string is 33 characters long=33
LENGTH OF EMPTY STRING = 0

































  All Information Presented Here is Proprietary to Digital Research

				 86




3.4.11	CONCAT

FUNCTION CONCAT( SOURCE1, SOURCE2, .... SOURCEn) : STRING;

      Return a string in which  all sources in the parameter  list are
concatenated. The  sources may  be string  variables, string literals,
or characters.  A SOURCE  of zero  length can  be concatenated with no
problem. If  the total  length of  all SOURCES  exceeds 256 bytes they
are  truncated  at  256  bytes.  See  the  note under COPY in the next
section concerning restrictions when using both CONCAT and COPY.

	EXAMPLE:

PROCEDURE CONCAT_DEMO;
VAR
  Sl,S2 : STRING;
BEGIN
  Sl	'left link, right link';
  S2	'root root root';
  WRITELN(Sl,'/',S2);
  sl := CONCAT(Sl,' ',S2,'!!!!!!');
  WRITELN(Sl);
end;

Output:

left link, right link/root root root
left link, right link root root root!!!!!!


























  All Information Presented Here is Proprietary to Digital Research

				 87





3.4.12 COPY

FUNCTION COPY( SOURCE, LOCATION, NUM_BYTES) : STRING;

      SOURCE  must  be  a  string.  LOCATION and NUM_BYTES are integer
expressions. Return a string  which contains the number  of characters
specified in NUM_BYTES  from SOURCE beginning  at the index  specified
in LOCATION. If  LOCATION is out  of bounds or  is negative, no  error
occurs. If NUM_BYTES  is negative or  NUM_BYTES plus LOCATION  exceeds
the length of the SOURCE, truncation occurs.

	EXAMPLE:

PROCEDURE COPY_DEMO;
BEGIN
  LONG_STR := 'Hi from Cardiff-by-the-sea';
  WRITELN(COPY(LONG-STR,9,LENGTH(LONG-STR)-9+1));
end;

Output:

Cardiff-by-the-sea

NOTE:

      COPY  and  CONCAT  are  "pseudo"  string returning functions and
have  only  one  statically  allocated  buffer  for  the return value.
Therefore, if these functions are used more than once within the  same
expression the  value of  each occurrence  of these  functions becomes
the   value   of    the   last   occurrence.    For   instance,    'IF
(CONCAT(A,STRING1) = (CONCAT(A,STRING2))' will always be true  because
the  concatenation  of  A  and  STRING1  is  replaced by that of A and
STRING2. Also, I WRITELN ( COPY (STRING1, 1, 4), COPY (STRING1,  5,4))
writes the second set of four characters in STRING1 twice.




















  All Information Presented Here is Proprietary to Digital Research

				 88





3.4.13	POS

FUNCTION POS( PATTERN, SOURCE 	INTEGER;

      Return the integer value of the position of the first  occurence
of PATTERN in SOURCE. If the pattern is not found a zero is  returned.
SOURCE  is  a  string  and  PATTERN  is  a  string,  a character, or a
literal.

	EXAMPLE:

PROCEDURE POS_DEMO;
VAR
  STR,PATTERN : STRING;
  CH : CHAR;
BEGIN
  STR := 'MT MicroSYSTEMS';
  PATTERN := 'croSY';
  CH := 'T';
  WRITELN('pos of ',PATTERN,' in ',STR,' is ', POS(PATTERN,STR));
  WRITELN(Ipos of ',CH,' in ',STR,' is ',POS(CH,STR));
  WRITELN(Ipos of ''z'' in ',STR,' is ',POS('z',STR));
end;

Output:
pos of croSY in MT MicroSYSTEMS is 6
pos of T in MT MicroSYSTEMS is 2
pos of ' z' in MT MicroSYSTEMS is 0


























  All Information Presented Here is Proprietary to Digital Research

				 89




3.4.14	DELETE

PROCEDURE DELETE( TARGET, INDEX, SIZE);

      TARGET  is  a  string.  INDEX  and SIZE are integer expressions.
Remove SIZE  characters from  TARGET beginning  at the  byte named  in
INDEX. If SIZE is zero no  action is taken. If it is  negative serious
errors result. If the INDEX plus  the SIZE is greater than the  TARGET
or  the  TARGET  is  empty,  the  data  and  surrounding memory can be
destroyed.

	EXAMPLE:

PROCEDURE DELETE_DEMO;
VAR
  LONG_STR : STRING;
BEGIN
  LONG_STR := '     get rid of the leading blanks';
  WRITELN(LONG_STR);
  DELETE(LONG_STR,1,POS('g',LONG_STR)-1);
  WRITELN(LONG_STR);
END;

Output:
      get rid of the leading blanks
get rid of the leading blanks




























  All Information Presented Here is Proprietary to Digital Research

				 90





3.4.15 	INSERT

PROCEDURE INSERT( SOURCE, DESTINATION, INDEX);

      DESTINATION  is  a  string.  SOURCE  is  a  character or string,
literal  or  variable.  INDEX  is  an  integer  expression. Insert the
SOURCE  into  the  DESTINATION  at  the  location  specified in INDEX.
SOURCE can  be empty.  If INDEX  is out  of bounds  or DESTINATION  is
empty,  destruction  of   data  occurs.  If   inserting  SOURCE   into
DESTINATION causes it to be longer than allowed it is truncated.

	EXAMPLE:

PROCEDURE INSERT_DEMO;
VAR
  LONG_STR : STRING;
  Sl : STRING[10];
BEGIN
  LONG_STR := 'Remember  Luke';
  Sl := 'the Force,';
  INSERT(Sl,LONG_STR,10);
  WRITELN(LONG_STR);
  INSERT(Ito use ',LONG_STR,10);
  WRITELN (LONG_STR)
end;

Output:
Remember the Force, Luke
Remember to use the Force, Luke

























  All Information Presented Here is Proprietary to Digital Research

				 91





3.4.16		ASSIGN

PROCEDURE ASSIGN( FILE, NAME );

      This procedure  is used  to assign  an external  file name  to a
file variable  prior to  a RESET  or a  REWRITE. FILE  is a file name,
NAME is  a literal  or a  variable string  containing the  name of the
file to be created. FILE may be  of any type but must be of  type TEXT
in order to use the special device names below.

      The  user  should  note  that  standard Pascal defines a "local"
file. Pascal/MT+ implements this  facility using temporary file  names
in the form  PASTMPxx.$$$ where xx  is sequentially assigned  starting
at zero at the beginning of each program. If an external file  REWRITE
is not preceeded by an ASSIGN then a temporary file name will also  be
assigned to  this file  before creation.  Locally declared  files in a
recursive environment may  not be used  as temporary files  unless the
user does an ASSIGN(<file>,'') to initialize the file.

      Below is  a summary  of device  names supported  in the CP/M run
time environment.

	Device names
	------------

	CON:	-	When used as input will echo input characters
			and echo CR as CR/LF and backspace [CHR(8)] as
			backspace, space, backspace
			When used as output will echo CR as CR/LF and
			CP/M will expand tabs to every 8 character
			positions. Line feed cannot be output.
	KBD:	-	CP/M console, input device only.
			No echo or interpretation. Cannot be used
			simultaneously with CON: input or output.
	TRM:	-	CP/M console, output device only.
			No interpretation (CP/M 2.X only)
	LST:	-	CP/M printer, output device only.
			No interpretation including no tab expansion
	RDR:	-	CP/M reader, input device only. Call auxiliary
			input routine located in the BIOS via the BDOS
			using function 3.

	PUN:	-	CP/M punch, output device only. Call auxiliary
			output routine located in the BIOS via the
			BDOS using function 4.









  All Information Presented Here is Proprietary to Digital Research

				 92


      These names  may be  used with  the ASSIGN  procedure as  in the
examples below:

	ASSIGN(CONIN,'CON:');
	ASSIGN(KEYBOARD,'KBD:');
	ASSIGN(CRT,'TRM:');
	ASSIGN(PRINTFILE,'LST:');

      There is a problem using  CON: and KBD: together because  of the
manner in  which these  function calls  are implemented.  In order  to
implement control-S, CP/M checks for typed characters when  performing
function  call  2,  i.e,  when  writing  to  CON:. If the user types a
character which  is not  a control-S  CP/M stores  this internally  in
anticipation of a subsequent call using function 1. Function 6  (which
is  used  by  KBD:)  always  goes  directly  to the BIOS for its input
ignoring any character which may  be present in this internal  buffer.
Therefore,  it  is  possible  for  a  program  to  appear to be losing
characters when, in fact, they are being stored internally by CP/M.






































  All Information Presented Here is Proprietary to Digital Research

				 93





3.4.17		WNB, GNB

FUNCTION GNB(FILEVAR: FILE OF PAOC):CHAR;
FUNCTION WNB(FILEVAR: FILE OF CHAR; CH:CHAR) : BOOLEAN;

      These functions allow  the user to  have BYTE level  access to a
file in a high speed manner. PAOC is any type which is a Packed  Array
Of  Char.  The  size  of  the  packed  array is optimally in the range
128..4095.

      GNB will allow the user to  read a file a byte-at-a-time. It  is
a function which returns a value  of type CHAR. The EOF function  will
be valid when the physical  end-of-file is reached but not  based upon
any  data  in  the  file.  Attempts  to  read past the end of the file
results in $FF being returned. See the files section of the appendix.

      WNB will allow the user to write a file a byte-at-a-time. It  is
a function which requires a file and a character to write. It  returns
a boolean  value which  is true  if there  was an  error while writing
that byte to the  file. No interpretation is  done on the bytes  which
are written.

      The  reason  GNB  and  WNB  are  used (as opposed to F^, GET/PUT
combinations)  is  that  they  are  significantly  faster because of a
larger buffer.

      See the sample program in the files section of the appendix.



























  All Information Presented Here is Proprietary to Digital Research

				 94





3.4-18		BLOCKREAD, BLOCKWRITE

BLOCKREAD (F:FILEVAR; BUF:ANY; VAR IOR:INTEGER; SZ,RB:INTEGER);
BLOCKWRITE(F:FILEVAR; BUF:ANY; VAR IOR:INTEGER; SZ,RB:INTEGER);

      These procedures are used  for direct CP/M disk  access. FILEVAR
is an untyped file (FILE;). BUF  is any array variable which is  large
enough to hold the  data. It may be  indexed. IOR is an  integer which
receives  the  returned  value  from  the  operating system. SZ is the
number of bytes to transfer and  RB is the relative block number.  For
CP/M environments the SZ must be an multiple of 128. SZ is related  to
the size of BUF. If  BUF is 128 bytes then  SZ must be 128. If  BUF is
4096 bytes then SZ may be as large as 4096. RB may be in the range  of
-1..32767. When RB is -1, sequential block transfer is assumed by  the
run-time  routines.  When  RB  is  greater  than  -1, the correct file
location is calculated by the  routine, and new extents are  opened as
needed.

      The data is transfered either to or from the users BUF  variable
for the specified number of bytes.


































  All Information Presented Here is Proprietary to Digital Research

				 95




3. 4. 19 OPEN

PROCEDURE OPEN	( FILE, TITLE, RESULT );

      The OPEN procedure  is provided to  increase the flexibility  of
Pascal/MT+  and  to  provide  compatibility  with previous releases of
Pascal/MT. FILE  is any  file type  variable. TITLE  is a string which
contains the  CP/M filename.  RESULT is  a VAR  INTEGER parameter  and
upon return from OPEN has the same value as IORESULT.

      The  OPEN  procedure  is  exactly  the  same  as  executing   an
ASSIGN(FILE,TITLE), RESET(FILE) and RESULT := IORESULT sequence.

	EXAMPLE:

	OPEN ( INFILE, 'A:FNAME.DAT', RESULT );






































  All Information Presented Here is Proprietary to Digital Research

				 96




3.4.20		CLOSE

PROCEDURE CLOSE	  ( FILE, RESULT );
PROCEDURE CLOSEDEL( FILE, RESULT );

      The  CLOSE  and  CLOSEDEL  procedures  are  used for closing and
closing with delete respectively.  The CLOSE procedure must  be called
to guarantee that data written to a file using any method is  properly
purged from  the file  buffer to  the disk.  The CLOSEDEL  is normally
used on temporary files to delete them after use. FILE and RESULT  are
the same as used in OPEN (see Section 3.4.19).

      Files are  implicitly closed  when an  open file  is RESET.  The
number of files which  may be open at  one time is CPU  dependent. For
CP/M  systems,  this  number  is  not  limited except by the amount of
memory available for file control blocks.

      The  CLOSE  procedure  is  used  in  the  file  section  of  the
appendix.



































  All Information Presented Here is Proprietary to Digital Research

				 97




3.4.21	PURGE

PROCEDURE PURGE( FILE );

      The  PURGE  procedure  is  used  to  delete a file whose name is
stored in a string.  The user must first  ASSIGN the name to  the file
and then execute PURGE.

	EXAMPLE:

	ASSIGN(F,'B:BADFILE.BAD');

	PURGE(F);	(* DELETE B:BADFILE.BAD )*









































  All Information Presented Here is Proprietary to Digital Research

				 98




3.4.22	IORESULT

FUNCTION  IORESULT : INTEGER;

      After each  I/O operation  the value  which is  returned by  the
IORESULT function is set by the run-time library routines. In  general
the value of IORESULT is system dependent. Never attempt to WRITE  the
IORESULT because it is reset to 0 before any I/O operation.

      The IORESULT function returns an integer from the BDOS which  is
altered  after  every  CP/M  file  access.  In  a CP/M environment the
general rule is that 255 means an error and any other value is a  good
result. This  is not  the case  in CLOSE  and WRITE/PUT/WNB.  In these
procedures a non-zero IORESULT value means error.

	Listed below are IORESULT values for CP/M:

PROCEDURE		VALUES
---------		-----
CLOSE			255 MEANS ERROR, ANYTHING ELSE IS OK
RESET			255 MEANS ERROR, ANYTHING ELSE IS OK
REWRITE			255 MEANS ERROR, ANYTHING ELSE IS OK
READ/READLN/GET		<> 0 MEANS END OF FILE, 0 MEANS OK
PAGE/WRITE/WRITELN/PUT	<> 0 MEANS ERROR, 0 MEANS OK
PURGE			0 ALWAYS RETURNED
SEEKREAD/SEEKWRITE	0 OPERATION SUCCESSFUL
			1 READING UNWRITTEN DATA
			2 CP/M ERROR
			3 CANNOT CLOSE CURRENT EXTENT
			4 SEEK TO UNWRITTEN EXTENT
			5 NEW EXTENT CANNOT BE CREATED (WRITE ONLY)
			6 SEEK PAST PHYSICAL END OF DISK
	EXAMPLE:

	ASSIGN(F,'C:HELLO');
	RESET(F);

	IF IORESULT = 255 THEN
	  WRITELN('C:HELLO IS NOT PRESENT');















  All Information Presented Here is Proprietary to Digital Research

				 99




3.4.23	SEEKREAD, SEEKWRITE

PROCEDURE SEEKREAD(F : ANYFILE; RECORD_NUM: O..MAXINT);
PROCEDURE SEEKWRITE(F : ANYFILE; RECORD_NUM : O..MAXINT);

      Random access is implemented only on CP/M 2.0 or greater.

      The random access procedures use the window variable for an  I/O
buffer.  The  user  must  assign  to  the  window  variable prior to a
SEEKWRITE  or  assign  from  the  window  variable  after  a SEEKREAD.
Samples  of  programs  using  these  procedures  are found in the file
section of the appendix.

	F^ := data;
	SEEKWRITE(F,RECORD_NUM);

	SEEKREAD(F,RECORD_NUM);
	data := F^;

      Files written using SEEKWRITE  are contiguous regardless of  the
record  size.  This  means  that   a  file  may  either  be   accessed
sequentially or  randomly, but  not without  executing a  CLOSE before
changing access modes.

      These procedures are more  useful than BLOCKREAD and  BLOCKWRITE
because they  perform the  same function,  are more  portable, and are
easier to use.

      Random access run  time support is  found in RANDOMIO.ERL  which
must be linked to resolve the references to SEEKREAD and SEEKWRITE.

      For IORESULT values see the section on IORESULT, 3.4.22.

      See the  file appendix  for more  information on  the action  of
these routines.



















  All Information Presented Here is Proprietary to Digital Research

				 100



3.4.24	READHEX, WRITEHEX

PROCEDURE READHEX   ( VAR F : TEXT; VAR W : ANYTYPE; SIZE : 1..2);
PROCEDURE WRITEHEX  ( VAR F : TEXT; EXPRESSION : ANYTYPE; SIZE: 1..2);

      To  perform  I/O  on  variables  of  type  WORD  or to write HEX
numbers use  these routines.  The EXPRESSION  is one  or two bytes and
SIZE indicates the number of bytes to be written.















































  All Information Presented Here is Proprietary to Digital Research

				 101




3.4.25		MEMAVAIL, MAXAVAIL

FUNCTION   MEMAVAIL : INTEGER;
FUNCTION   MAXAVAIL : INTEGER;

      The  functions  MEMAVAIL  and  MAXAVAIL  are used in conjunction
with NEW  and DISPOSE  to manage  the HEAP  memory area in Pascal/MT+.
The MEMAVAIL function returns the largest, never-allocated,  available
memory at any given  time irrespective of fragmentation.  The MAXAVAIL
function will first garbage collect, combine any contiguous fragments,
and then report the largest  block available. Note that if  the result
of these functions is a negative number when displayed, the amount  of
memory  remaining  is  larger  than  can  be  expressed  as a positive
integer.  The  return  value  could  be  displayed using WRITEHEX. The
MAXAVAIL function  can be  used to  force a  garbage collect  before a
time sensitive section of programming.

      The  Pascal/MT+  system  supports  fully  the  NEW  and  DISPOSE
mechanism  defined  by  the  Pascal  Standard.  The  run-time routines
required to  support the  full implementation  of NEW  and DISPOSE are
found in FULLHEAP.ERL  which must be  explicitly named when  linking a
program.

      See the appendix for more information on use of dynamic memory.






























  All Information Presented Here is Proprietary to Digital Research

				 102





3.4.26	WAIT

PROCEDURE WAIT(PORTNUM , MASK, POLARITY);

      PORTNUM and MASK are literal  or named constants. POLARITY is  a
boolean constant.

	WAIT generates a tight status wait loop:
	IN portnum
	ANI mask
	J?? $-4

where ?? is Z if polarity is false and is NZ if polarity is true.

      The  WAIT  procedure  does  not  generate  in-line  code for the
status loop.  A status  loop as  described is  constructed in the DATA
area and called by the  WAIT run-time subroutine. This means  that the
loop is fast but the call and return from the loop add a small  amount
of exection time. If time is critical use INLINE.

	EXAMPLE:

PROCEDURE WAIT_DEMO;
CONST
  CONSPORT = $F7; (* for EXO NOBUS-Z COMPUTER *)
  CONSMASK = $01;

BEGIN
  WRITELN('WAIT_DEMO........');
  WRITELN('WAITING FOR A CHARACTER');
  WAIT(CONSPORT,CONSMAXK,TRUE);
  WRITELN ('THANKS!');
end;





















  All Information Presented Here is Proprietary to Digital Research

				 103



3.4.27	RIM85, SIM85

FUNCTION RIM85 : BYTE;
PROCEDURE SIM85(VAL : BYTE);

      These routines use  the special 8085  instructions RIM and  SIM.
A call is generated to a procedure which contains the instruction.  In
the CP/M  environment the  HEAP area  grows from  the end  of the data
area and the stack frame (for recursion) grows from the top of  memory
down. The hardware stack register in a CP/M environment is  pre-loaded
with the contents  of absolute location  0006 unless the  $Z toggle is
used to  override this.  The stack  frame grows  starting at 512 bytes
below  the  initialized  hardware  value.  The  user  should  refer to
Section 2.2.4.4 for more information on the $Z toggle.









































  All Information Presented Here is Proprietary to Digital Research

				 104




3.4.28	QUICK REFERENCE GUIDE TO BUILT-INS

In alphabetical order within each group:

Character array manipulation routines:

	PROCEDURE FILLCHAR ( DESTINATION, LENGTH, CHARACTER);
	PROCEDURE MOVELEFT ( SOURCE, DESTINATION, NUM BYTES);
	PROCEDURE MOVERIGHT( SOURCE, DESTINATION, NUM-BYTES);

Bit and byte manipulation routines:

	PROCEDURE CLRBIT( BASIC_VAR, BIT_NUM);
	FUNCTION  HI	( BASIC_VAR )		: INTEGER;
	FUNCTION  LO	( BASIC_VAR )		: INTEGER;
	PROCEDURE SETBIT( BASIC_VAR, BIT NUM);
	FUNCTION  SHL	( BASIC_VAR, NUM)	: INTEGER;
	FUNCTION  SHR	( BASIC_VAR, NUM)	: INTEGER;
	FUNCTION  SWAP	( BASIC_VAR		: INTEGER;
	FUNCTION  TSTBIT( BASIC_VAR, BIT-NUM)	: BOOLEAN;

String handling routines:

	FUNCTION  CONCAT ( SOURCE1, SOURCE2,....,SOURCEn ) : STRING;
	FUNCTION  COPY	 ( SOURCE, LOCATION, NUM_BYTES)    : STRING;
	PROCEDURE DELETE ( TARGET, INDEX, SIZE );
	PROCEDURE INSERT ( SOURCE, DESTINATION, INDEX);
	FUNCTION  LENGTH ( STRING )			   : INTEGER;
	FUNCTION  POS	 ( PATTERN, SOURCE)		   : INTEGER;

File handling routines:

	PROCEDURE ASSIGN    ( FILE, NAME
	PROCEDURE BLOCKREAD ( FILE, BUF, IOR, NUMBYTES, RELBLK);
	PROCEDURE BLOCKWRITE( FILE, BUF, IOR, NUMBYTES, RELBLN);
	PROCEDURE CLOSE	    ( FILE, RESULT );
	PROCEDURE CLOSEDEL  ( FILE, RESULT );
	FUNCTION  GNB	    ( FILE )	   : CHAR;
	PROCEDURE IORESULT 		   : INTEGER;
	PROCEDURE OPEN	    ( FILE, TITLE, RESULT );
	PROCEDURE OPENX	    ( FILE, TITLE, RESULT, EXTENT );
	PROCEDURE PURGE	    ( FILE );
	PROCEDURE READHEX   ( FILE, VAR, SIZE);
	PROCEDURE SEEKREAD  ( FILE, RECORD_NUMBER);
	PROCEDURE SEEKWRITE ( FILE, RECORD_NUMBER);
	FUNCTION  WNB	    ( FILE, CHAR ) : BOOLEAN;
	PROCEDURE WRITEHEX  ( FILE, EXPRESSION, SIZE);

Miscellaneous routines:
	FUNCTION  @CMD : PTR_TO_STRING;
	FUNCTION  ADDR   ( VARIABLE REFERENCE )	: INTEGER;
	PROCEDURE EXIT;
	FUNCTION  MAXAVAIL : INTEGER;

  All Information Presented Here is Proprietary to Digital Research

				 105




	FUNCTION  MEMAVAIL : INTEGER;
	FUNCTION  RIM85 : BYTE;
	PROCEDURE SIM85 (VAL : BYTE);
	FUNCTION  SIZEOF( VARIABLE OR TYPE NAME) : INTEGER;
	PROCEDURE WAIT(PORTNUM , MASK, POLARITY);

















































  All Information Presented Here is Proprietary to Digital Research

				 106





3.5 	CHAINING
	--------

      There are times  when programs exceed  the memory available  and
also  many  times  when  segmentation  of programs for compilation and
maintenance  purposes  is  desired.  The  Pascal/MT+ system provides a
"chaining"  mechanism  in  which  one  program may transfer control to
another program.

      The  user  must  declare  an  untyped  file  (FILE;) and use the
ASSIGN and  RESET procedures  to initialize  the file.  Following this
the user may execute  a call to the  CHAIN procedure passing the  name
of  the  file  variable  as  a  single parameter. The run-time library
routine will  then perform  the appropriate  functions to  load in the
file opened by  the user using  the RESET statement.  The size of  the
various programs does not matter,  except that the data must  be above
the largest  program when  chaining from  a small  to a large program.
This means that a small program may  chain to a large one and a  large
program may chain to a small  one. If the user desires to  communicate
between the chained program the user may choose to communicate in  two
ways: shared global variables and ABSOLUTE variables.

      Using the shared global variable method the user must  guarantee
that at  least the  first section  of global  variables is  to be  the
communication area and  is exactly the  same in the  two programs that
wish to communicate.  The remainder of  the global variables  need not
be the same  and the declaration  of external variables  in the global
section will not affect this  mapping. In addition to having  matching
declarations, the user must use the /D option switch available in  the
linker  (see  Section  2.3.2.4)  to  place  the  variables at the same
location in all programs that wish to communicate.

      Using  the  ABSOLUTE  variable  method  the user would typically
define a record which is used as a communication area and then  define
this record  at an  absolute location  in each  module. This  does not
require  the  use  of  the  /D  switch  in the linker but does require
knowledge of the memory used by the program and the system.

      To maintain the HEAP across  a chain, SYSMEM may be  declared as
an EXTERNAL  INTEGER. SYSMEM  contains the  address of  the top of the
heap. Also, if using FULLHEAP,  @EFL : INTEGER and @FRL  : ARRAY[l..4]
OF  BYTE  contain  neccessary  information  for FULLHEAP. These may be
saved  in  the  global  data  area  and  reset at the beginning of the
chained-to program.  The  use of the /D  linker switch is required  to
address  the  globals  for  all  programs  in  the  chain  at the same
location.

      Listed below  are two  example programs  which communicate  with
each other using  the ABSOLUTE variable  method and the  first program
will CHAIN to the second program  which will print the results of  the
first program's execution:



  All Information Presented Here is Proprietary to Digital Research

				 107



(* PROGRAM #1 IN CHAIN DEMONSTRATION *)

PROGRAM CHAIN1;
TYPE
  COMMAREA = RECORD
		I,J,K : INTEGER
	     END;
VAR
  GLOBALS : ABSOLUTE [$8000] COMMAREA;
  CHAINFIL: FILE;

BEGIN (* MAIN PROGRAM # 1 *)
  WITH GLOBALS DO
    BEGIN
      I	:= 3;
      J	:= 3;
      K	:= I * J
    END;
  ASSIGN(CHAINFIL,'A:CHAIN2.COM');
  RESET(CHAINFIL);
  IF IORESULT = 255 THEN
    BEGIN
      WRITELN('UNABLE TO OPEN CHAIN2.COM');
      EXIT
    END,
  CHAIN(CHAINFIL)
END.			(* END CHAIN1 *)

(* PROGRAM #2 IN CHAIN DEMONSTRATION *)

PROGRAM CHAIN2;
TYPE
  COMMAREA = RECORD
		I,J,K : INTEGER
	     END;
VAR
  GLOBALS : ABSOLUTE [$8000] COMMAREA;

BEGIN (* PROGRAM #2 *)
  WITH GLOBALS DO
    WRITELN('RESULT OF ',I,' TIMES ',J,' IS =', K)

END.			(* RETURNS TO OPERATING SYSTEM WHEN COMPLETE *)












  All Information Presented Here is Proprietary to Digital Research

				 108





3.6	INTERRUPT PROCEDURES
	--------------------

      A  special  procedure  type  is  implemented  in Pascal/MT+: the
interrupt  procedure.  The  user  selects  the vector to be associated
with each interrupt. The procedure is declared as follows:

	PROCEDURE INTERRUPT [ <vec num> } <identifier> ;

      Interrupt procedures may exist ONLY in the main program so  that
the  interrupt  vectors  are  loaded  correctly.  They  may  not  have
parameters  lists  but  may  have  local  variables  and access global
variables. The compiler generates code at the begining of the  program
to load the  vector with the  procedure address. For  8080/Z80 systems
the vector  number should  be in  the range  of 0..7.  For Z80  mode 2
interrupts the user may declare  an ABSOULUTE variable to allocate  an
interrupt table and then use the ADDR function to fill in this  table.
The INLINE facility would be  used in a Z80 environment  to initialize
the I-register.

      The  compiler  generates  code  to  push  the  registers  at the
begining of procedure  execution and pop  the registers and  re-enable
interrupts at  the end  of execution  of the  procedure. The  Z switch
does not  cause the  generation of  the Z80  'RETI' instruction  as so
many interrupt modes are possible on the Z80.

      The  user  should  note  that  the  system  does  not   generate
re-entrant  code.  Typically  interrupt  procedures  will  set  global
variables and  not perform  other procedure  calls or  input / output.
Stay away from SETS, STRINGS,  procedure calls, file I/O, and  calling
CP/M, and  any routines in the run-time packages  which contain  data.
This  is  because  the  8080  and  Z80  do  not  have addressing modes
sophisticated  enough  to  manipulate  items  on the stack so that the
return address is constantly being  removed from the stack and  stored
in a statically allocated  temporary location. CP/M users  should note
that I/O through the CP/M BDOS typically re-enables interrupts.

      To disable interrupts around sections of Pascal code use  INLINE
and the mini-assembler to place EI (enable interrupt) and DI  (disable
interrupt) instructions around the code.

      Listed below is a simple example program which waits for one  of
four  switches  to  interrupt  and  then  toggles the state of a light
which is  attached to  the switch.  The I/O  ports for  the lights are
0..3 and the switches interrupt using restarts 2, 3, 4 and 5.









  All Information Presented Here is Proprietary to Digital Research

				 109



PROGRAM INT_DEMO;
CONST
	LIGHT1 = 0;	(* DEFINE I/O PORT CONSTANTS *)
	LIGHT2 = 1;
	LIGHT3 = 2;
	LIGHT4 = 3;

	SWITCH1 = 2;	(* DEFINE INTERRUPT VECTORS *)
	SWITCH2 = 3;
	SWITCH3 = 4;
	SWITCH4 = 5;
VAR
  LIGHT_STATE : ARRAY [LIGHT1..LIGHT4] OF BOOLEAN;
  SWITCH_PUSH : ARRAY [LIGHT1..LIGHT4] OF BOOLEAN;

  I : LIGHT1 .. LIGHT4;

PROCEDURE INTERRUPT [ SWITCH1 ] INT1;
BEGIN
  SWITCH_PUSH[LIGHT1] := TRUE
END;

PROCEDURE INTERRUPT [ SWITCH2 ] INT2;
BEGIN
  SWITCH_PUSH[LIGHT2] := TRUE
END;

PROCEDURE INTERRUPT [ SWITCH3 ] INT3;
BEGIN
  SWITCH_PUSH[LIGHT3] := TRUE
END;

PROCEDURE INTERRUPT [ SWITCH4 ] INT4;
BEGIN
  SWITCH-PUSH(LIGHT4] := TRUE
END;

BEGIN	(* MAIN PROGRAM *)
  (* INITIALIZE BOTH ARRAYS *)
  FOR I := LIGHT1 TO LIGHT4 DO
    BEGIN
      LIGHT STATE[I] := FALSE;	(* ALL LIGHTS OFF *)
      SWITCH_PUSH[I] := FALSE;	(* NO INTERRUPTS YET *)
    END;

  ENABLE;	(* LET THE USERS HAVE AT IT! *)

  REPEAT

    REPEAT	(* UNTIL INTERRUPT *)
    UNTIL SWITCH_PUSH[LIGHT1] OR SWITCH_PUSH[LIGHT2] OR
	  SWITCH_PUSH[LIGHT3] OR SWITCH_PUSH[LIGHT4];




  All Information Presented Here is Proprietary to Digital Research

				 110




    FOR I := LIGHT1 TO LIGHT4 DO (* SWITCH LIGHTS *)
      IF SWITCH PUSH[Ij THEN
        BEGIN
	  SWITCH_PUSH[I] := FALSE;
	  LIGHT_STATE[I] := NOT LIGHT_STATE[I]; (* TOGGLE IT *)
	  OUT[(I)] := LIGHT_STATE[I]
        END

  UNTIL FALSE;	(* FOREVER DO THIS LOOP *)

END. (* OF PROGRAM *)











































  All Information Presented Here is Proprietary to Diqital Research

				 111



3.7	NON-STANDARD DATA ACCESS METHODS
	--------------------------------

3.7.1		INP AND OUT ARRAYS

      The Pascal/MT+  system provides  a feature  which allows  direct
manipulation  of  Input  and  Output  hardware ports. Two pre-declared
arrays, INP and OUT,  are provided which are  of type BYTE and  may be
subscripted with port number constants and expressions. The INP  array
may be used only in expressions and the OUT array may be used only  on
the LEFT-hand side of an assignment statement. If the values from  INP
are assigned to  variables of type  INTEGER the most  significant byte
will contain 00.

      The arrays may  be subscripted with  integer expressions in  the
range  0-255.  Two  types  of  syntax  are  used with this feature. if
constant subscripts  are used  the code  is generated  in-line. If the
subscripts are expressions a special  syntax is required in which  the
expression is enclosed inside parentheses within the square  brackets.
With this second method a call  is generated to a run-time routine  to
handle variable port I/O.

      If these arrays  are used in  a recursive environment  they must
always use  the format  with parentheses  inside the  square brackets,
regardless of whether the index  is an expression or constant.  Again,
a call is made to the appropriate run-time library routines to  handle
variable port I/O. See the examples below:

	OUT[(portnum + i)] := $88; (with expressions and/or recursion)
	OUT[O] := $88; (with named or literal constants, no recursion)
	OUT[(O)] := $88 (with recursion)
	J := INP[(portnum)]; (with expressions and/or recursion)

      The compiler is  not always able  to catch a  case in which  the
parentheses must be  used but are  not used. If  your program compiles
but does not work, you may  be missing parentheses in your INP  or OUT
statement.

3.7.2		REDIRECTED INPUT/OUTPUT METHOD

      In addition to the standard I/O facilities, Pascal/MT+  provides
a  mechanism  by  which  Pascal/MT+  programmers  can  write their own
character level I/O  drivers in Pascal/MT+.  This facility allows  the
ROM-based  program  to  be  system  independent.  It  also allows user
written character input and output  routines which get or write  their
data to  strings or  I/O ports  to use  the conversion  routines built
into the system read/write code.

      The  redirected  I/O  facility  is  simple  and easy to use. The
user must simply place the address of the user-supplied get  character
routine (for READ's) or  the user-supplied put-character routine  (for
WRITE's), in square  brackets, after the  left parenthesis and  before
the parameter list in a READ, WRITE or WRITELN statement.


  All Information Presented Here is Proprietary to Digital Research

				 112




	EXAMPLE:

	READ( [ ADDR(getch) ], ...);
	WRITELN( [ ADDR(putch) ], ...);

      The "getch" and  "putch" routines may  be written in  Pascal/MT+
or  in  assembly  language.  The  parameter  requirements  for   these
routines are as follows:

	FUNCTION getch : CHAR;
	PROCEDURE putch( outputch: CHAR);

      The declaration of  these routines must  be as shown.  The names
need not be  getch/putch, but the  get character routine  must have no
parameters and the  put character routine  must have one  parameter of
type CHAR.  The user  may assign  the address  of the  procedure to  a
pointer using the ADDR function  and then specify this pointer,  e.g.,
READ([P],...  ,  which  does  not  save  execution  time but does save
typing time.

      Note  that  because  EOLN  and  EOF  require  a file on which to
operate,  READLN  and  EOF/EOLN  cannot  be used with re-directed I/O.
Because  READLN  uses  EOLN,  reading  into  STRING  variables  (which
requires  use  of  READLN)  is  not  allowed. This is because the @RST
(read  string)  routine  attempts  to  read  directly from the console
device when  no file  is specified.  The user  should rewrite the @RST
routine to  perform any  and all  input and  editing functions desired
for the target  system console device.  This does not  affect programs
which do not use redirected I/O.

      See the  appendix on  Pascal files  for a  sample redirected I/O
program.

3.7.3	ABSOLUTE VARIABLES

<absolute var> ::= ABSOLUTE [ <constant> ] <var>

      ABSOLUTE variables may be declared if the user knows the address
at compile time.  The user declares  variable(s) to be  absolute using
special syntax in  a VAR declaration.  After the colon  (:) and before
the  type  of  the  variable(s)  the  user places the keyword ABSOLUTE
followed by the address of the variable in brackets ([...]) : ABSOLUTE
variables are not  allocated any space  in the user's  data segment by
the  compiler  and  the  user  is  responsible for making sure that no
compiler  allocated  variables  conflict  with the absolute variables.
NOTE: STRING  VARIABLES MAY  NOT EXIST  AT ALL  LOCATIONS. On the 8080
strings must  be at  100H..FFFFH. This  is done  so that  the run-time
routines can  detect the  difference between  a string  address and  a
character on the top of the stack.

	I:	ABSOLUTE [$8000] INTEGER;
	SCREEN:	ABSOLUTE [$C000] ARRAY[O..15] OF ARRAY[O..63) OF CHAR;


  All Information Presented Here is Proprietary to Digital Research

				 113




3.8	INLINE AND MINI ASSEMBLER
	-------------------------

      Pascal/MT+ has  a very  useful built-in  feature called  INLINE.
This  feature  allows  the  user  to  insert  data  in the middle of a
Pascal/MT+  procedure  or  function.  In  this  way small machine code
sequences  and  constant  tables  may  be  inserted  into a Pascal/MT+
program without using externally assembled routines.

3.8.1		SYNTAX

      The syntax for the INLINE feature  is very similar to that of  a
procedure call in Pascal. The word  INLINE is used followed by a  left
parenthesis '(' followed by any  number of arguments separated by  the
slash '/'  character and  terminated by  a right  parenthesis ')'. The
arguments  between  the   slashes  must  be   constants  or   variable
references which evaluate to constants. These constants can be of  any
of the following  types: CHAR, STRING,  BOOLEAN, INTEGER or  REAL. The
user should note that  a STRING in quotes  does not generate a  length
byte but  simply the  data for  the string.  Note that  in stack frame
addressing  (either  by  using  $S+  or  on  more  sophisticated CPUs)
variables  will  evaluate  to  the  offset  into  the appropriate data
segment. For CPUs  which use static  addresssing (e.g. 8080,  8085 and
Z80) the address is the absolute address of the data.

      To facilitate branching,  the syntax *+n  and *-n where  n is an
integer is included as legal operand to INLINE. For example,

	INLINE("IN / $03/
	       "ANI/ $02/
	       "JNZ/ *-4 );

The location which the '*' references is the previous opcode, not  the
address of the '*' character.

      Literal constants which  are of type  integer will be  allocated
one byte if the value falls in the range 0..255. This is not the  case
for named, declared, integer constants which will always be  allocated
two bytes.

      In addition to constant data the Pascal/MT+ system also provides
a built-in  mini assembler  feature for  8080/8085 CPUs.  The user may
place the  assembly language  mnemnonic after  a double  quote and the
first phase  of the  compiler will  translate this  mnemonic into  the
appropriate hex value (e.g. "MOV A,M will translate into $7E). In  the
future this may  be extended to  handle other processors.  The list of
valid opcodes for the mini-assembler may be found in the appendix.







  All Information Presented Here is Proprietary to Digital Research

				 114




	EXAMPLE

	INLINE("LHLD	/	(* LHLD OPCODE FOR 8080 *)
	       "VAR1	/	(* REFERENCE VARIABLE   *)
	       "SHLD	/	(* SHLD OPCODE FOR 8080 *)
	       "VAR2	);	(* REFERENCE VARIABLE   *)

      The INLINE facility  can be used  to insert native  machine code
or  to  build  compile-time  tables.  The  following two sections give
examples of each of these uses.

3.8.2	CODE EXAMPLES

      The  code  below  gives  an  example  of  how  to use the INLINE
facility to write  a procedure which  calls CP/M and  returns a value.
This routine is present in the run-time library as @BDOS.

	EXAMPLE:

		FUNCTION @BDOS(FUNC:INTEGER; PARM:WORD):INTEGER;
	CONST
	  CPMENTRYPOINT = 5;	(* SO IT ALLOCATES 2 BYTES )*
	VAR
	  RESULT : INTEGER;	(* SO WE CAN STORE IT HERE *)
	BEGIN
	  INLINE( $2A / FUNC /		(* LHLD FUNC	*)
		  $4D / 		(* MOV C,L	*)
		  $2A / PARM /		(* LHLD PARM	*)
		  $EB / 		(* XCHG		*)
		  $CD /	CPMENTRYPOINT /	(* CALL BDOS	*)
		  $6F / 		(* MOV L,A	*)
		  $26 /	$00 /		(* MVI H,O	*)
		  $22 / RESULT );	(* SHLD RESULT	*)

	  @BDOS := RESULT;	(* SET FUNCTION VALUE *)
	END;


















  All Information Presented Here is Proprietary to Digital Research

				 115




3.8.3	CONSTANT DATA GENERATION

      The program fragment below demonstrates how the INLINE  facility
can be used to construct a compile time table:

	EXAMPLE:

	PROGRAM DEMO_INLINE;

	TYPE
	    IDFIELD = ARRAY [l..4] OF ARRAY [l..10] OF CHAR;

	VAR
	  TPTR : ^IDFIELD;

	PROCEDURE TABLE;
	BEGIN
	  INLINE(	'MTMICROSYS' /
			'SOFTWARE  ' /
			'POWER     ' /
			'TOOLS.....' );
	END;

	BEGIN (* MAIN PROGRAM *)
	  TPTR : = ADDR (TABLE);

	  WRITELN(TPTR^[3]);	(* SHOULD WRITE 'POWER     ' *)

	END.

      If the  INLINE code  is within  a recursive  module, taking  the
ADDR of TABLE does not give the address of TABLE because of additional
code generated by recursion management. An extra six bytes of code are
generated without the $Q toggle in effect, and five bytes of code  are
generated with the $Q toggle.

      Also, the table has  to be in the  same module as the  statement
which takes the ADDR of TABLE.
















  All Information Presented Here is Proprietary to Digital Research

				 116




3.9	RECURSION AND NON-RECURSION
	---------------------------

      Pascal/MT+ does  not produce  code to  utilize recursion  unless
requested by the user. This is because the code size is increased  and
the execution speed is reduced if recursive code is generated but  not
used. The way in which recursion is used is described in the  compiler
toggle section, 2.2.4.2.

      Return addresses for all  procedures are stored on  the hardware
stack.  This  stack  contains  128  bytes  in  the  default  state. if
recursion is deeply nested, this stack size may not be sufficient  for
running  the  program.  If  this  is  the  case  the program may start
overwriting local data or global data as the recursion continues.  The
solution is a  larger hardware stack.  Section 5 includes  information
on making the hardware stack larger.






































  All Information Presented Here is Proprietary to Digital Research

				 117







	CHAPTER 4: RUN-TIME ERROR HANDLING
	-----------------------------------

      The Pascal/MT+ system supports three types of run-time checking:
range, exception, and input/output.

	o Range checking is discussed in Section 4.1.

	o Section 4.2 presents exception checking .

	o A method by which error handling may be tailored by the
	  user is described in Section 4.3.

	o Run-time I/O checking is discussed in Section 4.4.

      The default  condition of  the system  is that  range checks are
disabled and  exception checks  are enabled.  I/O checks  are disabled
because the  routine which  handles I/O  errors is  not part of PASLIB
but in source code to  be modified by the user  to suit his / her  own
needs.

      The general philosophy is  that error checks and  error routines
will set boolean flags. These  boolean flags along with an  error code
will be loaded onto the stack and the built-in routine @ERR is  called
with  these  two  parameters.  The  @ERR  routine  will  then test the
boolean parameter. If it is false  then no error has occurred and  the
@ERR  routine  will  exit  back  to  the  compiled  code and execution
continues. If it is true  the @ERR routine take appropriate  action as
described in the following sections.

      Listed below are the error numbers passed to the @ERR routine:

	Value	meaning
	-----	-------
	  1	Divide by 0 check
	  2	Heap overflow check (unused, see below)
	  3	String overflow check (unused, see below)
	  4	Array and subrange check
	  5	Floating point underflow
	  6	Floating point overflow
	  7	9511 transcendental error











  All Information Presented Here is Proprietary to Digital Research

				 119




4.1	RANGE CHECKING
	--------------

      Range checking is performed on array subscripts and on  subrange
assignments.  It  is  not  performed  when  READing  into  a  subrange
variable. When range checking is enabled the compiler generates  calls
to @CHK  for each  array subscript  and subrange  assignment. The @CHK
routine leaves a boolean on the stack and the error code number 4, and
the compiler  generates calls  to @ERR  after the  @CHK call. If range
checking is enabled @ERR prints a message and asks whether to continue
or abort. If range checking  is disabled and an array  subscript falls
outside  the  valid  range,  unpredictable  results  will  occur.  For
subrange assignments the value will be truncated at the byte level.

4.2	EXCEPTION CHECKING
------------------

      Exception  checking  is  performed  on  integer  and real number
divide by 0, real number underflow and overflow, and string  overflow.
It is enabled by default. In the current release $X does not turn  off
exception checking.  When exception  checking is  enabled the compiler
will load the error flags  (zero divide, string overflow, real  number
underflow and overflow) as needed and call the @ERR routine after each
operation which  would set  the flags.  If a  floating point underflow
occurs,  0.0  is  returned  but  no  message  is printed by @ERR. If a
floating  point  overflow  occurs,  a  message  is printed and a large
number is returned.  Divide by zero  results in a  maximum value being
returned, heap overflow does nothing and string overflow truncates.

4.3	USER SUPPLIED HANDLERS
	----------------------

      It is possible for the user to write an @ERR routine to be  used
instead of the system routine. The user should declare the routine as:

PROCEDURE @ERR(ERROR:BOOLEAN; ERRNUM:INTEGER);

      The routine  will be  called, as  mentioned above,  each time an
error check is needed and this routine should check the ERROR variable
and exit if it is FALSE. The user may decide the appropriate action if
the value is  true. To use  your @ERR routine  instead of the  routine
contained in PASLIB, link your own routine ahead of PASLIB to  resolve
the references  to @ERR.  The values  of ERRNUM  are as  shown at  the
beginning of this chapter.










  All Information Presented Here is Proprietary to Digital Research

				 120




4.4	I/O ERROR HANDLING

      The  run-time  routine,  @BDOS,  does  not perform any I/O error
handling except to return the CP/M error code in IORESULT for the user
to check.  An alternative @BDOS  routine is found in XBDOS.SRC on  the
distribution disk.  When this XBDOS  calls the BDOS with the CP/M  I/O
functions 15, 16, 21, and 22 (OPEN or RESET, CLOSE, WRITE or PUT,  and
REWRITE, respectively) ; it generates  a call to IOERR passing  it the
CP/M function call number.  The IOERR routine, found in IOERR.SRC, may
be altered to handle these I/O errrors as the user desires.

      To use the I/O error  handling code, compile both IOERR.SRC  and
XBDOS.SRC.  The  relocatable  files  that  result  may be built into a
library using  the file  named IOCHK.BLD  on the  distribution disk as
input to LIB/MT+.  This creates a library called IOCHK.ERL which  must
be linked before PASLIB and cannot be searched because all  references
to @BDOS  are generated  by PASLIB.  See the  section in  Chapter 2 on
using the librarian.

      @BDOS need not  be declared external  because all references  to
@BDOS  are  generated  by  PASLIB.  Also,  all references to IOERR are
generated by @BDOS so IOERR is not declared as external.
































  All Information Presented Here is Proprietary to Digital Research

				 121







CHAPTER 5: ANATOMY OF A PASCAL/MT+ PROGRAM
	-------------------------------------------

    o  This chapter presents the data types and how they are stored.
       It also gives details on the use of strings.

    o  Also, a description of the layout of a Pascal/MT+ COM file in
       memory under CP/M is presented.

5.1	DATA TYPES
	----------

      This  section  describes  how  the  standard and extended Pascal
data types are implemented in Pascal/MT+. A summary of the data  types
appears in the following table.

	Data type	Size			Range
	CHAR		1 8-bit-byte		0..255
	BOOLEAN		1 8-bit-byte		false..true
	INTEGER		1 8-bit-byte		0..255
	INTEGER		2 8-bit-bytes		-32768..32767
	BYTE		1 8-bit-byte		0..255
	WORD		2 8-bit-bytes		0..65535
	BCD REAL	10 8-bit-bytes		18 digits,4 decimal
	FLOATING REAL	4 8-bit-bytes		lOE-17..10E+17
	STRING		1-256 bytes		----------------
	SET		32 8-bit-bytes		0..255

5.1.1 	CHAR

      The data type CHAR is implemented using one 8-bit byte for  each
character. The  reserved word  PACKED is  assumed on  arrays of  CHAR.
CHAR variables may have the  range of CHR(0) .. CHR(255).  When pushed
on the  stack a  CHAR variable  is 16  bits with  the high  order byte
containing 00.  This is  to allow  ORD, ODD,  CHR and  WRD to all work
together.

5.1.2 	BOOLEAN

      The data type  BOOLEAN is implemented  using one 8-bit  byte for
each  BOOLEAN  variable.  When  pushed  on  the  stack 8 bits of 0 are
pushed to provide compatibility with built in operators and

  All Information Presented Here is Proprietary to Digital Research

				 123





routines. The reserved  word PACKED is  allowed but does  not compress
the data  structure any  more than  one byte  per element (this occurs
with  and  without  the  packed  instruction).  ORD(TRUE)  =  0001 and
ORD(FALSE) = 0000. The BOOLEAN operators AND, OR and NOT operate  only
on ONE  byte. The  user is  refered to  the &,  | and ~ operators (see
Section 7.8) for 16-bit boolean operators.

		-------------------
		|X|X|X|X|X|X|X|0/1|	(X means don't care)
		-------------------

5.1.3		INTEGER

      The data type INTEGER is  implemented using two 8-bit bytes  for
each INTEGER  variable. The  order of  the bytes  is CPU dependent. In
the 8080, 8085, Z80, 8086 and  8088 the low byte is in  lower numbered
address and the high order 8 bits are in the higher numbered  address.
MAXINT  =  32767  and  INTEGERS  can  have the range -32768..32767. An
integer subrange declared  to be within  the 0..255 occupies  only one
byte  of  memory  instead  of  two  bytes.  Integer  constants  may be
hexadecimal numbers by  preceeding the hex  number with a  dollar sign
(e.g. $0F3B).

5.1.4		REAL

      The implementation of the data type REAL in Pascal/MT+ has  been
done in two different ways to serve the needs of two different  market
areas.

      For  business  applications   the  REAL  data   type  has   been
implemented in binary coded decimal  (BCD) with 18 digits and  4 fixed
decimal  places.  Automatic  rounding  is  done after the fourth place
during  calculations  and  also  at  the  specified place if formatted
output is used.  The format of  a REAL BCD  number is: bytes  1..9 are
digits packed two to  the byte, and byte  10 contains the sign:  0 for
positive and $FF for negative.  The B switch in the  compiler (Section
2.2) must be used to tell the compiler to save 10 bytes for each  real
number rather than the default four bytes. The file BCDREALS.ERL  must
be linked when using the BCD format. This format does not support  the
transcendental routines or the square root function.

	----------------------------------------------
	| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8  | 9 | 10    |
low mem |d|d|d|d|d|d|d|d|d|d|d|d|d|d|.d|d|d|d|  sign | hi mem
	----------------------------------------------

  All Information Presented Here is Proprietary to Digital Research

				 124





      For scientific and engineering  applications the REAL data  type
has been implemented using  binary floating point. The  floating point
used in  Pascal/MT+ is  fully compatible  with the  AMD 9511  hardware
floating  point  unit.  Thirty-two  (32)  bits  (4-bytes)  of data are
required  to  implement  a  floating  point  number.  The  first  byte
contains the mantissa  sign, the exponent  sign and the  exponent. The
remaining  three  bytes  contain  the  mantissa. The precision of this
format is approximately 6.5 digits. The reader is referred to the  AMD
9511 hardware manual for further details regarding the binary format.

	__________________________________________________
	|                                 |    |    |    |
low mem	| exp sign/mantissa sign/exponent | ms |    | ls | high mem
	|                                 |    |    |    |
	--------------------------------------------------

	ms = most significant bits
	ls = least significant bits

      The floating point  format is the  default used by  the compiler
when real numbers are used in a program.

      Pascal/MT+  implements  this  floating  point  data type in both
software  and  hardware.  The  standard  floating point package system
comes with software run-time  (FPREALS.ERL). The file named  AMDIO.SRC
is used to modify  port addresses for the  9511 to adapt this  version
of the run-time package to the user's system. See the appendix on 9511
interface for more details about  configuring the software to use  the
9511 chip.

5.1.5	BYTE

      The BYTE  data type  occupies a  single byte.  It is  compatible
with  both  INTEGER  and  CHAR  types.  This  can  be very useful when
manipulating control characters,  handling character arithmetic,  etc.
Characters and integers may be assigned to a BYTE.

5.1.6	WORD

      WORD  is  an  unsigned  native  machine  word.  All   arithmetic
performed on expressions  of type WORD  is unsigned. In  addition, all
comparisons are  also unsigned.  The WORD  data type  is designed such
that it is always the same size as the pointer data type.











  All Information Presented Here is Proprietary to Digital Research

				 125




5.1.7	STRING

5.1.7.1		Definition

      The  pre-declared  type  STRING  is  like  a  packed  array   of
characters in  which the  byte 0  contains the  dynamic length  of the
string and bytes  1 through n  contain the characters.  Strings may be
up to 255  characters in length.  The default length  is 80 characters
which may be altered when a  variable of type string is declared  (see
example below).

      The string "This is a  Wottle" is sixteen characters in  length.
The  following  diagram  shows  how  these  characters are stored in a
string declared to be 20 characters in length.

	____________________________________________
low mem |16|T|h|i|s| |i|s| |a| |W|o|t|t|l|e|?|?|?|?| high mem
	--------------------------------------------

      If  the  number  of  characters  in  the string is less than the
declared length,  those bytes  on the  end are  not defined. Note that
the length is stored in the  first byte and the total number  of bytes
required for the string is 17.

	EXAMPLE:

VAR
  LONG_STR:	STRING;		{This may contain up to 80 characters}
  SHORT_STR:	STRING[10];	{This may contain up to 10 characters}
  VERY_LONG_STR : STRING[255];	{This may contain up to 255 characters,
				 the maximum allowed.}

5.1.7.2		Assignment

      Assignment to a string variable  may be made via the  assignment
statement, reading  into a  string variable  using READ  or READLN, or
the pre-defined string functions and procedures.

	EXAMPLE:

PROCEDURE ASSIGN;
VAR
  LONG_STR : STRING;
  SHORT_STR : STRING[12];










  All Information Presented Here is Proprietary to Digital Research

				 126



BEGIN

  LONG_STR := 'This string may contain as many as eighty characters';
  WRITELN(LONG_STR);

  WRITE('type in a string 10 characters or less');
  READLN(SHORT_STR);
  WRITELN(SHORT_STR);

  SHORT_STR := COPY(LONG_STR,1,11);
  WRITELN('COPY(LONG_STR..)=',SHORT_STR);
END;

Output:

This string may contain as many as eighty characters
type in a string 10 characters or less : {123456} (USER INPUT)
123456
COPY(LONG-STR..)=This string m

      Individual characters in  a string variable  are accessed as  if
the string is an array of characters. Thus, normal array  subscripting
via  constants,  variables,  and  expressions  allows  assignment  and
access to  individual bytes  within the  string. Access  to the string
over  its  entire  declared  length  is  legal  and  does  not cause a
run-time error even if  an access is made  to a portion of  the string
which is beyond the current dynamic length. If the string is  actually
20 characters long  and the declared  length is 30  then STRING[25] is
accessible.

EXAMPLE

PROCEDURE ACCESS;
VAR
  I : INTEGER;
BEGIN
  I := 15;
  LONG_STR := '123456789abcdef';
  WRITELN(LONG_STR);
  WRITELN(LONG_STR[6], LONG_STR[I-5]);
  LONG_STR[16] := '*'
  WRITELN (LONG_STR[16]);
  WRITELN(LONG_STR); (* will still only write 15-characters *)
END;

Output:

123456789abcdef
6a
*
123456789abcdef




  All Information Presented Here is Proprietary to Digital Research

				 127




5.1.7.3 Comparisons

      Comparisons  are  valid  between  two  variables  of type string
(regardless  of  their  length)  or  between  a variable and a literal
string. Literal  strings are  sequences of  characters between  single
quote marks.   Comparisons may  also be  made between  a string  and a
character. The compiler 'forces' the  character to become a string  by
using the  CONCAT buffer,  therefore comparison  of the  result of the
CONCAT function and a character is not meaningful as this would result
in an always equal comparison.

EXAMPLE

PROCEDURE COMPARE;

VAR
  Sl,S2	: STRING[10];
  CH1	: CHAR;

BEGIN
  Sl := '012345678';
  S2 :=	'222345678';

  IF Sl < S2 THEN
    WRITELN(Sl,' is less than ',s2);

  Sl := 'alpha beta';
  IF Sl = 'alpha beta   ' THEN
    WRITELN('trailing blanks dont matter')
  ELSE
    WRITELN('trailing blanks count');
  IF Sl = '	alpha beta' THEN
    WRITELN('blanks in front don''t matter')
  ELSE
    WRITELN('blanks in front do matter');
  IF S1 = 'alpha beta' THEN
    WRITELN(Sl,' = ',Sl);
  Sl  := 'Z';
  CH1 := 'Z';
  IF Sl = CH1 THEN
    WRITELN('strings and chars may be compared');
END;

Output:

012345678 < 222345678
trailing blanks don't matter
blanks in front do matter
alpha beta = alpha beta
strings and chars may be compared




  All Information Presented Here is Proprietary to Digital Research

				 128




5.1.7.4		Reading and Writing Strings

      Strings  may  be  written  to  a  text  file  using the WRITE or
WRITELN  procedure.  WRITELN  will  put  a  carriage-return  line-feed
following the string. Reading a  string is always done via  the READLN
statement  because  strings  are  terminated  with  a  carriage return
line-feed.  Using  READ   will  not  work   because  the   end-of-line
characters are incorrectly processed. Tabs are expanded when they  are
read into a variable of the string data type.

5.1.8 		SET

      The SET  data type  is always  stored as  a 32  byte item.  Each
element of the  set is stored  as one bit.  The low order  bit of each
byte is the first bit in that byte of the set. Shown below is the  set
'A'..'Z' (bits 65..122)

	Byte number 00 01 02 03 04 05 06 07 08 09 OA OB OC ... 1F
		    -- -- -- -- -- -- -- -- -- -- -- -- -- ... --
	Contents    00 00 00 00 00 00 00 00 FE FF FF 07 00     00


































  All Information Presented Here is Proprietary to Digital Research

				 129




5.2	EXECUTION TIME COM FILE STRUCTURE
	----------------------------------

5.2.1	MEMORY LAYOUT AND SYSTEM VARIABLES

      The memory layout for a program which has been compiled,  linked
and loaded into memory  for execution by CP/M  is shown below. If  the
user did  not specify  the /D  switch when  using the  linker then the
code area contains both code and data.

Memory Layout:

+----+-------///-----+--------///---+----->   <----+-----+-----------+
|low | program code  | program data | heap   local | H/W | CP/M BDOS |
|mem | area including|	area	    | area   var   | stk | and BIOS  |
|    | run-time lib. | with /D:     |	     stack*|     |	     |
+----+-------///-----+--------///---+----->   <----+-----+-----------+
^    ^                              ^              ^     ^           ^
0   100H			  SYSMEM-->    <--@SFP	bdos	   mem

*  Only used in recursive environments.

      The  symbol  ///  indicates  variable  size area output from the
linker. The heap grows toward high memory and the local variable stack
grows toward  low memory.  The local  variable stack  is used  only in
programs which contain  the $S+ switch  (for recursion). The  hardware
stack  contains  the  procedure  return  addresses  and  the temporary
evaluation stack  for expressions.  The local  variable stack contains
parameters  and  local  procedural  variables.  The  external  integer
SYSMEM points to the "top" of the heap and is initialized to point  to
the first location following the  data area. SYSMEM is updated  by the
NEW routine.  The external  integer @SFP  points to  the "top"  of the
local variable stack and is initialized to be the top of the  hardware
stack  minus  128  bytes  and  is  updated by the @LNK (allocate stack
frame)  and  @ULK  (deallocate  stack  frame)  routine.  The  built-in
function  MEMAVAIL  (in  systems  which   do  not  use  FULLHEAP)   is
calculated by (@SFP - SYSMEM).

5.2.2	HARDWARE STACK SIZE

      The hardware stack is initialized to 128 bytes but the user  may
change this by manipulating the run-time variable @SFP as an  external
integer and subtracting the desired additional space (or adding if you
want to make  it smaller) required  for the hardware  stack from @SFP.
See the example below:

	VAR @SFP:EXTERNAL INTEGER;

	(* in main program only!!! *)

	@SFP := @SFP - MORE_HW_STACK_SPACE_IN_BYTES;



  All Information Presented Here is Proprietary to Digital Research

				 130




      If the code  is being run  on an interrupt  driven system it  is
often necessary to increase the size of the hardware stack.

5.2.3	PROGRAM STRUCTURE

      The Pascal/MT+ compiler generates  program modules which have  a
very simple  structure. At  the beginning  of the  module is located a
jump table  containing a  jump to  each procedure  or function  in the
module. Space is reserved at the  beginning of the jump table for  the
jump  instruction  to  the  main  program.  This jump is unused if the
module is a MODULE and not a PROGRAM. In addition, in a PROGRAM  there
are 16-bytes  of header  information (in  non-overlayed programs these
are NOPs) which are used for overlay information. At the beginning  of
the  main  program  the  compiler  generates  code  to  load the stack
pointer  based  upon  the  contents  of  location  6 which is the CP/M
standard. Users of  ROM based object  code must use  the $Z switch  to
set the  initial stack  pointer for  their ROM  requirements. Also the
compiler generates a  call to the  @INI routine which  initializes the
INPUT and OUTPUT text files and the stack frame pointer used when  the
$S+ toggle is activated. Again ROM based users will typically wish  to
re-write the @INI routine to suit their needs.

































  All Information Presented Here is Proprietary to Digital Research

				 131


























































  All Information Presented Here is Proprietary to Digital Research

				 132




	    CHAPTER 6: STAND-ALONE OPERATION OF A PROGRAM

      The user  may wish  to run  programs written  in Pascal/MT+ in a
ROM based system. This has been  a design goal from the beginning  and
has been done successfully by many users.

      The  steps  required  to  put  a  program into ROM are presented
below.

1)	Set the  hardware stack  pointer using  $Z (Section  2.2.4.4).
	The hardware stack default  address is the address  pointed to
	by locations  6 and  7 in  your CP/M  system. If  more room is
	needed for the hardware stack (128 bytes is the default),  see
	the section in Chapter 5 describing how to save more space.

2)	If the program is performing any I/O you have three choices:

	a) Use redirected I/O for all READ and WRITE statements: This
	   replaces the run-time character I/O routines with user
	   written I/O routines (Section 3.7.2).
	b) Rewrite GET, @RNC, and @WNC: @RNC is the run-time read-next
	   character  routine,  and  @WNC  is the write-next-character
	   routine.  GET  must  be  rewritten because the read-integer
	   and read-real routines call GET.
	c) Build a simulated CP/M BDOS in your org 0 PROM: If you  are
	   constructing  a  program  to  run  in a totally stand-alone
	   environment (e.g. An Intel  SBC-80/10 board) you can  write
	   an assembly language module to  be linked in front of  your
	   program which:   1) jumps around  the code which  simulates
	   the BDOS and  2) simulates the  CP/M BDOS for  functions 1:
	   Console Input,  2:   Console Output  and 5:   List  Output.
	   The function number will be in the C-register and the  data
	   for output will be  in the E-register. For  input (function
	   1) return  the data  in the  A-register. All  registers are
	   free for use and there  is nothing on the stack  except the
	   return  address.   This  is  just  a  suggestion,   Digital
	   Research will not provide detailed application support  for
	   this method.

3)	The user  of a  ROM based  system may  wish to  shorten and/or
	eliminate the INPUT and OUTPUT FIB storage located in the @INI
	module.  This   storage  is   required  for   TEXT  file   I/O
	compatibility  but  may   not  be  needed   in  a  ROM   based
	environment. The user  should be cautious  and make sure  that
	any   changes   to   INPUT   and   OUTPUT   are  also  handled
	correspondingly in @RST (read a  string from a file) and  @CWT
	(wait for EOLN to be true on a file). Run-time package  source
	code not accompanying the distribution disks may be  purchased
	separately. Check the  list in Chapter  1 for run-time  source
	accompanying the software. If  the user's program does  not do
	any READ{LN} and/or WRITE{LN}  calls and is not  recursive and
	does not use the heap or overlays, then the @INI procedure can
	be rewritten in the user's program as:

  All Information Presented Here is Proprietary to Digital Research

				 133




	PROCEDURE @INI;
	BEGIN
	END;

4)	When  using  the  PROCEDURE  INTERRUPT  [vector] construct for
	interrupt  procedures  in  a  ROM  based system, note that the
	compiler attempts  to store  into the  interrupt vectors. This
	cannot be done in a  ROM environment. The user must  construct
	an assembly language module and link this as the main  program
	(first file). This assembly  language module must contain  JMP
	instructions at the interrupt vector locations to jump to  the
	Pascal  interrupt  routines.  The  locations  of the interrupt
	routines may be found by using the /M linker switch.

5)	DIVMOD.MAC is provided in source code form because the integer
	and real divide routines contain a direct call to CP/M for the
	divide  by  0  error  message.  The user must make appropriate
	adjustments if this error may ever occur during the  execution
	of his / her program.

6)	Link any changed run-time routines before linking the run-time
	library to  resolve the  references, making  sure that  the /S
	switch is used:

		LINKMT USERPROG,MYWNC,MYRNC,GET,MYINI,PASLIB/S

7)	Strings cannot  live below  100H so  if you  have any constant
	strings (either  named or  literal) in  the beginning  of your
	program it is suggested that you fill out the remaining  space
	in the first PROM  with a table or  just with a DS  to get the
	Pascal/MT+  program  to  exist  at  locations  greater   100H.
	Remember, if you  put tables and/or  data first that  you must
	jump  around  them  to  begin  execution of the Pascal program
	starting with its first byte.

	Listed below are three skeletons for the @INI, @RNC, and  @WNC
	routines which can be used in ROM environments.

















  All Information Presented Here is Proprietary to Digital Research

				 134




;--------------------------------------------------------------------;
;	SAMPLE INITIALIZATION ROUTINE                                ;
;--------------------------------------------------------------------;

	PUBLIC	@INI
	PUBLIC	@SYSIN		;SYSTEM INPUT VECTOR
	PUBLIC	@SYSOUT		;SYSTEM OUTPUT VECTOR
	PUBLIC	INPUT		;DEFAULT INPUT FIB
				;THIS MUST BE PRESENT EVEN IF NO
				;FILE I/O IS DONE
	PUBLIC	OUTPUT		;AGAIN MUST BE PRESENT EVEN IF NO
				;FILE I/O IS DONE
	EXTRN	@RNC
	EXTRN 	@WNC

@INI:
	LXI	H,@RNC
	SHLD	@SYSIN
	LXI	H,@WNC
	SHLD	@SYSOUT

;
;	... ADD MORE THERE FOR HEAP, ETC. PRUNE FROM STANDARD @INI
;
	RET
	DSEG

@SYSIN:	DS	2
@SYSOUT: DS	2

INPUT:	DS	1		;DUMMY FIB
OUTPUT:	DS	1		;DUMMY FIB
	END			;AND THAT'S A SIMPLE ONE





















  All Information Presented Here is Proprietary to Digital Research

				 135




;--------------------------------------------------------------------;
;	SAMPLE @RNC - READ NEXT CHARACTER ROUTINE                    ;
;--------------------------------------------------------------------;

	PUBLIC @RNC
@RNC:
	; INCLUDE CODE HERE TO GET CHARACTER INTO A-REG AND
	; ECHO IT. ALSO IF USER WANTS TO SIMULATE CON:
	; THE DRIVER MUST ECHO BACKSPACE AS <BACKSPACE, SPACE,
	; BACKSPACE> AND CR AS CR/LF

	MOV	L,A
	MVI	H,0
	XTHL			;PUT FUNC VALUE ON STACK AND
				;RET ADDR IN HL
	PCHL			;RETURN
	END

;--------------------------------------------------------------------;
;	SAMPLE @WNC - WRITE NEXT CHARACTER ROUTINE                   ;
;--------------------------------------------------------------------;

	PUBLIC		@WNC

@WNC:
	POP	H		;GET RET ADDR
	XTHL			;PUT IT BACK AND GET PARM CHAR

	; CODE HERE TO WRITE CHARACTER IN L-REG TO OUTPUT DEVICE
	; IF USER WANTS TO SIMULATE CON: COMPLETELY THE USER
	; MUST OUTPUT CR AS CR/LF

	RET
	END




















  All Information Presented Here is Proprietary to Digital Research

				 136




	      CHAPTER 7: PASCAL/MT+ LANGUAGE DEFINITION
	------------------------------------------

7.1	INTRODUCTION
	------------

The  purpose  of  Chapter  7  is  to  define  the language features of
Pascal/MT+ which are  common to each  implementation of the  compiler.
Those features of Pascal/MT+ which are not part of the Pascal language
as it is defined in Jensen and Wirth are discussed in more detail than
the features which are identical  to the Jensen and Wirth  definition.
Therefore, if you do not know Pascal it is recommended that a copy  of
Jensen and  Wirth's 'User  Manual and  Report' be  studied as you read
this chapter. The chapter headings are  the same as those used in  the
'Report'. In each section BNF (Backus Normal Form) syntax is  provided
for  reference.  The  complete  BNF  description  of  the  language is
present in an appendix.

    o  An overview of the Pascal/MT+ language is presented in 7.2.

    o  Legal letters, digits, and symbols are shown in 7.3.

    o  Identifier syntax and significant characters are in Section
       7.4. Also hex number format is shown.

    o  7.5 presents constant definitions.

    o  Data type definitions in Section 7.6 introduce three new
       types and syntax for declaring them.

    o  Section 7.7 presents variable declarations.

    o  Expressions and operators are treated in Section 7.8.

    o  7.9 deals with statements.

    o  In 7.10 information on procedure declarations is found.
       Conformant arrays are discussed with sample procedures.
       Function declarations are treated in 7.11.

    o  Input and Output is discussed in 7.12.

    o  Finaly, 7.13 discusses programs and modules.











  All Information Presented Here is Proprietary to Digital Research

				 137




7.2	SUMMARY OF THE PASCAL/MT+ LANGUAGE
	----------------------------------

      Features  of  the  ISO  Pascal  include  the  data  types  REAL,
INTEGER, CHAR, BOOLEAN, multidimensional ARRAYS, user-defined RECORDS,
POINTER types, File variables,  user defined TYPES and  CONSTANTS, and
SETS (implemented in  this version with  a base type  of 256 one  byte
elements), ENUMERATED types, and SUBRANGE types.

      Also  included  in  ISO  Pascal  are  PROCEDURES, FUNCTIONS, and
PROGRAMS. Passing procedures and  functions as parameters to  a Pascal
routine is part of the ISO  standard, as well as conformant arrays  in
which arrays  of the  same index  type and  element type but different
sizes may  be passed  to the  same procedure.  Supported at the syntax
level are external parameters with the PROGRAM statement.

      TYPED and TEXT  files are supported  as defined in  the standard
using  the  Pascal  routines  RESET,  REWRITE,  GET, PUT, READ, WRITE,
READLN,  and  WRITELN.  The  default  I/O  files  INPUT and OUTPUT are
defined.

      All   ISO    statements    are   supported    including    WITH,
REPEAT ... UNTIL,  CASE, WHILE loops,  FOR loops, IF..THEN..ELSE,  and
GOTO.

      PACK and UNPACK are supported  but do not affect the  outcome of
the program  (data structures  are always  packed at  the byte level).
NEW  and  DISPOSE  are  implemented  and  allocate and deallocate HEAP
space.

      Modular  compilation   is  an   extension  of   MT+   compilers.
Variables and routines  may be made  public and/or private  and may be
called from  any other  module or  main program.  This feature  allows
easy inclusion  of relocatable  assembly language  as separate modules
in a final program.

      The   extended   data   types   STRING,   BYTE,   and  WORD  are
implemented in all  versions of the  Pascal compiler. The  STRING type
includes  a  length  byte  followed  by  the  maximum  number of bytes
possible. Routines  are supplied  to INSERT  a character  or a string,
DELETE from a string,  find the POSition of  a character in a  string,
COPY a portion of one string  to another, and CONCATenate two or  more
strings and/or characters together. BYTE  is a one byte data  item for
representing numbers from 0 to 255.  WORD is CPU dependent but is  two
bytes for 8-bit CPU's and four bytes for 16-bit CPU's.

      Additional   procedures   to   manage   files   on   disk    are
implemented. A file on disk  is associated with an internal  file, may
be  closed  or  deleted.  RANDOM  files  are supported in all versions
except those running under CP/M 1.4 and CP/M 1.4 compatible  operating
systems.



  All Information Presented Here is Proprietary to Digital Research

				 138




      Manipulating  BITS  and  BYTES  is  done using routines to TEST,
SET, CLEAR, SHIFT RIGHT and LEFT, return HI or LOW of a variable,  and
SWAP the high and low bytes of a varible.

      Miscelaneous  routines  to  access  items  in  a  program are to
return the  address of  a variable  or routine,  return the  size of a
variable  or  type,  move  a  given  number  of  bytes from one memory
location to another, fill a data item with a certain character.  Also,
the amount of  HEAPspace available at  any given  time  is accessable.
Garbage collection on the HEAP is supported.

      Logical operators for non-booleans is implemented.

      HEX literal numbers may be used with a dollar sign

      Include files are supported.

      An ELSE clause on the CASE statement is provided.

      Program CHAINING  and OVERLAYS  are supported.  Chaining is such
that the  code for  one program  is totally  replaced by  code for the
next  program,  but  heap  space  may  be  maintained  across a CHAIN.
Overlays are desribed in Chapter 3.































  All Information Presented Here is Proprietary to Digital Research

				 139




7.3	NOTATION, TERMINOLOGY, AND VOCABULARY
	-------------------------------------

<letter> ::= A | B | C | D | E | F | G | H | I | J |
	     K | L | M | N | 0 | P | Q | R | S | T |
	     U | V | W | X | Y | z | a | b | c | d |
	     e | f | g | h | i | j | k | 1 | m | n |
	     n | 0 | p | q | r | s | t | u | v | w |
	     x | y | z | @

<digit>	 ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
	     A | B | C | D | E | F | {only allowed in HEX numbers}

<special symbol> ::= {reserved words are listed in the appendix}
	     +  |  -  |  *  |  /  |  =  |  <> |  <  |  >  |
	     <= |  >= |  (  |  )  |  [  |  ]  |  {  |  }  |
	     := |  .  |  ,  |  ;  |  :  |  '  |  ^  |

	     {the following are additional or substitutions:}
	     (. |  .) |  ~  |  \  |  ?  |  !  |  |  |  $  |  &

	     ~, \, and ? are synonyms   (see Section 7.8.1.1)
	     !, and | are synonyms	(see Section 7.8.1.2)
	     &				(see Section 7.8.1.3)

Extensions:

      The symbol '@' is  a  legal letter in  addition to  those listed
in the   'Report.'  This   has  been   added  because   the   run-time
library  routines  are  written  using  this  special character as the
first letter of their name.  By adding '@' conflict with user names is
avoided.  Users are allowed  to call  the run-time  library  routines.
See Section 7.4 for further information.

      A  comment beginning with '(*' must end with  a '*)'.  A comment
beginning with '{' must end with '}'.

<comment>::= { < any characters > } |
		(* < any characters > *)

To allow nested comments the begin comment delimiter must be the  same
as the  end comment  delimiter. Thus,  in Pascal/MT+  the following is
legal:

	(* outer comment ...{ inner comment....}...outer comment *)









  All Information Presented Here is Proprietary to Digital Research

				 140




7.4	IDENTIFIERS, NUMBERS, AND STRINGS
	---------------------------------

<identifier>	   ::= <letter> {<letter or digit or underscore>}
<letter or digit or underscore> ::= <letter> | <digit> | _

<digit sequence>   ::= <digit> | { <digit> }
<unsigned integer> ::= $ <digit sequence> |
		       # <digit sequence> |
			 <digit sequence>
<unsigned real>	   ::= <unsigned integer> . <digit sequence> |
		       <unsigned integer> . <digit sequence>
		       E <scale factor>                      |
		       <unsigned integer> E <scale factor>
<unsigned number>  ::= <unsigned integer> | <unsigned real>
<scale factor>	   ::= <unsigned integer> | <sign><unsigned integer>
<sign>		   ::= + | -

<string>	   ::= ' <character> {<character>}' | ''

      All identifiers are significant  to eight characters.   External
identifiers  may  be  significant  to  only  six  or  seven characters
depending upon  the host  systems.   The underscore  character (_)  is
legal between letters  and digits in  an identifier and  is ignored by
the compiler, i.e. A_B is equivalent to AB. Whether the identifier  is
upper or lower case does not  matter, i.e ab is equivalent to  AB, aB,
and Ab. Identifiers may begin with an '@' character. This is to  allow
declaration of  external run-time  routines within  a Pascal  program.
Users  are,  in  general,  advised  to  avoid  the  '@'  character  to
eliminate  the  chance  of  conflict  with  run-time  routine   names.
Because  the  ISO  standard  defines  to  '@'  be equivalent to '^', a
compiler switch,  '@', causes  the character  to be  removed from  the
<letter> production and  become the pointer  symbol.  This  means that
'@' is no longer available for identifiers.

      Numbers may be hex  as well as decimal.  Placing a '$' in  front
of an integer number  causes it to be  interpreted as a hex  number by
the compiler.  The symbol  <digit> now  includes: 'A',  'B', 'C', 'D',
'E' and 'F'. These may be upper or lower case.















  All Information Presented Here is Proprietary to Digital Research

				 141




7.5	CONSTANT DEFINITIONS
	--------------------

<constant identifier> ::= <identifier>
<constant>	      ::= <unsigned number>           |
			  <sign><unsigned number>     |
			  <constant identifier>       |
			  <sign><constant identifier> |
			  <string>
<constant definition> ::= <identifier> = <constant>



      In addition to all  constant declarations available in  standard
Pascal, Pascal/MT+ supports declaration of a null string constant:

	EXAMPLE:

		nullstr = '';



































  All Information Presented Here is Proprietary to Digital Research

				 142




7.6	DATA TYPE DEFINITIONS

<type>		  ::= <simple type>     |
		      <structured type> |
		      <pointer type>
<type definition> ::= <identifier> = <type>

7.6.1	SIMPLE TYPES

<simple type>	  ::= <scalar type>   |
		      <subrange type> |
		      <type identifier>
<type identifier> ::= <identifier>

7.6.1.1 Scalar Types

<scalar type> ::= ( <identifier> { , <identifier>})


7.6.1.2 Standard Types

The following types are standard in Pascal/MT+

INTEGER REAL BOOLEAN CHAR

BYTE WORD STRING

      The  following  additional  standard  types exist in Pascal/MT+.
See Section  5.1 for  information on  representation and  usage of all
standard and structured types.

	STRING	: Packed array [ O..n ] of char;
		  byte 0 is dynamic-length byte
		  bytes l..n are characters.

	BYTE	: Subrange 0..255 with special attribute that
		  it is compatible also with CHAR type
	WORD	: Unsigned integer.
















  All Information Presented Here is Proprietary to Digital Research

				 143




7.6.1.3	Subrange Types

<subrange type> ::= <constant> .. <constant>

7.6.2		STRUCTURED TYPES

<structured type>	   ::= <unpacked structured type>  |
			       PACKED <unpacked structured type>
<unpacked structured type> ::= <array type>  |
			       <record type> |
			       <set type>    |
			       <file type>

      The reserved word PACKED is detected but because all  structures
are packed at the BYTE level  even if the PACKED reserved word  is not
found, it has no effect. The same is true for UNPACK.

7.6.2.1 Array Types


<array type>	 ::= <normal array> |
		     <string array>
<string array>	 ::= STRING <max length>
<max length>	 ::= [ <intconst> ] |
		     <empty>
<intconst>	 ::= <unsigned integer> |
		     <int const id>
<int const id>	 ::= <identifier>
<normal array>	 ::= ARRAY [ <index type> {,<index type>}] OF
		     <component type>
<index type>	 ::= <simple type>
<component type> ::= <type>

      Variables of type STRING have  a default length of 81  bytes (80
data  characters)  .  A  different  length  can be specified in square
brackets  following  the  word  STRING.  The  length  must be either a
literal or  declared constant  and represents  the length  of the DATA
portion (i.e.  one more  byte is  actually allocated  for the length).
For example, STRING[5] or STRING[XYZ], where XYZ is a constant (XYZ  =
5)  ,  would  cause  allocation  of  six  bytes  of data storage for a
variable of this type.













  All Information Presented Here is Proprietary to Digital Research

				 144




7.6.2.2 Record Types

<record type>	  ::= RECORD <field list> END
<field list>	  ::= <fixed part>                  |
		      <fixed part> ; <variant part> |
		      <variant part>
<fixed part>	  ::= <record section> {;<record section>}
<record section>  ::= <field identifier> {,<field identifier>} : <type>
		      <empty>
<variant part>	  ::= CASE <tag field> <type identifier> OF
		      <variant> {;<variant>}
<variant>	  ::= <case label list> : (<field list>)
		      <empty>
<case label list> ::= <case label> {,<case label>}
<case label>	  ::= <constant>
<tag field>	  ::= <identifier> : |
		      <empty>


7.6.2.3 Set Types

<set type> ::= SET OF <base type> <base type> ::= <simple type>

      The maximum  range of  a base  type is  0-255. For  example, the
set of [0..10000] or the set of  0..256 are not legal, but the set  of
CHAR or set of 0..255 are legal.




























  All Information Presented Here is Proprietary to Digital Research

				 145




7.6.2.4	File Types
	----------

<file type> ::= file {of <type>}


      Both  typed  and  untyped  files  are allowed. Untyped files are
used for CHAINING  (see the Section  3.5) and are  also used with  the
BLOCKREAD  and  BLOCKWRITE  procedures  (see  Section  3.4.). The user
should be extremely careful when using untyped files.

      When  wishing  to  read  a  file  of  ASCII characters and using
implied conversions  for integers  and reals  the user  should use the
predefined type TEXT.  TEXT is NOT  exactly the same  as FILE OF  CHAR
but has conversion implied in READ and WRITE procedure calls and  also
may be used with  READLN and WRITELN. A  file that is of  type TEXT is
declared  in  the  following  manner:  'VAR  F  : TEXT'. The INCORRECT
syntax for declaring a  TEXT file is 'VAR  F : FILE OF  TEXT'. See the
appendix on Pascal file handling.



7.6.3	Pointer Types

<pointer type> ::= ^ <type identifier>

      Pointer types  are identical  to the  standard except  that weak
type checking  exists when  the RELAXED  type checking  feature of the
compiler is  enabled (the  default). In  this case  pointers and WORDs
used  as  pointers  are  compatible   in  all  cases.  Also,   pointer
arithmetic  is  allowed.  Note  that  with  compiler switch @, the '^'
character may  be replaced  with '@'  (the two  may be  mixed within a
program).

7.6.4	TYPES AND ASSIGNMENT COMPATIBILITY

      The  most  common  "standard  Pascal"  question  concerns   type
conflict errors messages  from the compiler.  Types must be  identical
if  the  variable  is  passed  to  a  VAR  parameter.  Types  must  be
compatible  for  expressions  and  assignment statments. To understand
the difference between compatible and identical types the user  should
think of types as pointers  to compile-time records. If you  declare a
type (such  as T=ARRAY  [l..10] OF  INTEGER) then  any thing  which is
declared as type T really points to the record describing type T.  If,
on the other hand, you declare two variables to be as below,

	VAR
	  Al : ARRAY [l..10] OF INTEGER;





  All Information Presented Here is Proprietary to Digital Research

				 146



	  A2 : ARRAY [l..10] OF INTEGER;

they are  not identical  since the  compiler created  a new record for
each type and therefore Al and A2  do not point to the same record  in
memory at compile-time.  The general rule  is that if  you cannot find
your way back to a type definition then the types are not identical.

      Below  is  a  section  from  the  ISO  draft standard (DPS-7185)
which is  available from  the American  National Standards  Institute.
The ISO standard definition of compatible types is:

    Types Tl and T2 shall be designated compatible if any of
    the four statements that follow is true.
	(a) Tl and T2 are the same type.
	(b) Tl is a subrange of T2 or T2 is a subrange of Tl, or
	    both Tl and T2 are subranges of the same host type.
	(c) Tl and T2 are designated packed or neither Tl nor T2
	    is designated packed.
	(d) Tl and T2 are string-types * with the same number of
	    components.

    ... Assignment compatibility. A value of type T2 shall
    be designated assignment-compatible with a type Tl if any
    of the five statements that follow is true.
	(a) Tl and T2 are the same type, that is neither a file
	    type nor a structured-type with a file component (this
	    rule is to be interpreted recursively).
	(b) Tl is the real-type and T2 is the integer-type.
	(c) Tl and T2 are compatible ordinal-types ** and the
	    value of type T2 is in the closed interval specified by
	    the type Tl.
	(d) Tl and T2 are compatible set-types and all the
	    members of the value of type T2 are in the closed
	    interval specified by the base-type of Tl.
	(e) Tl and T2 are compatible string-types

    At any place where the rule of assignment-compatibility
    is used:
	(a) It shall be an error if Tl and T2 are compatible
	    ordinal-types ** and the value of type T2 is not in the
	    closed interval specified by the type Tl.
	(b) It shall be an error is Tl and T2 are compatible set
	    types and any member of the value of type T2 is not in
	    the closed interval specified by the base-type of the
	    type Tl.

    * string-types in ISO Pascals are arrays of characters.
    ** ordinal types are named subranges of numbers or enumerations.

      CHR,  ORD,  ODD,  and  WRD  are  type conversion operators which
generate no code but tell the compiler that the following 8 or 16  bit
data item is to  be considered to be  of type CHAR, INTEGER,  BOOLEAN,
or WORD respectively. These may be used in expressions and with  value
parameters but not VAR parameters.

  All Information Presented Here is Proprietary to Digital Research

				 147



7.7	DECLARATIONS AND DENOTATIONS OF VARIABLES
	-----------------------------------------

<variable declaration> ::= <variable> <type> | <empty>

<variable>	::= <var>          |
		    <external var> |
		    <absolute var>
<external var>	::= EXTERNAL <var>
<absolute var>	::= ABSOLUTE [ <constant> <var>
<var>		::= <entire variable>    |
		    <component variable> |
		    <referenced variable>

      More information on ABSOLUTE  variables may be found  in Section
3.7 on Non-standard data access methods.

7.7.1	ENTIRE VARIABLES

<entire variable>	::= <variable identifier>
<variable identifier> 	::= <identifier>


7.7.2	COMPONENT VARIABLES


<component variable> ::= <indexed variable> |
			 <field designator> |
			 <file buffer>


7.7.2.1 Indexed Variables

<indexed variable> ::= <array variable> [<expression> {,<expression>}]
<array variable>   ::= <variable>




      STRING variables  are to  be treated  as a  PACKED array of CHAR
for  subscripting  purposes.  The  valid  range is 0..max-length where
max-length is 80 for a default length.













  All Information Presented Here is Proprietary to Digital Research

				 148




7.7.2.2 Field Designators

<field designator> ::= <record variable> . <field identifier>
<record variable>  ::= <variable>
<field identifier> ::= <identifier>


7.7.2.3		File Buffers

<file buffer> ::= <file variable> ^ <file variable> ::= <variable>


7.7.3	REFERENCED VARIABLES

<referenced variable> ::= <Pointer variable> ^ <pointer variable>
::= <variable>






































  All Information Presented Here is Proprietary to Digital Research

				 149




7.8	EXPRESSIONS
	-----------

<unsigned constant> ::= <unsigned number>                            |
			<string>                                     |
			NIL                                          |
			<constant identifier>
<factor>	    ::= <variable>                                   |
			<unsigned constant>                          |
			<function designator>                        |
			( <expression> )                             |
			<logical not operator> <factor>              |
			<set>
<set>		    ::= [ <element list> ]
<element list>	    ::= <element> {,<element>}			     |
			<empty>
<element>	    ::= <expression>                                 |
			<expression> .. <expression>
<term>		    ::= <factor> <multiplying operator> <factor>
<simple expression> ::= <term>                                       |
			<simple expression> <adding operator> <term> |
			<adding operator> <term>
<expression>	    ::= <simple expression>                          |
			<simple expression> <relational operator>    |
			<simple expression>

      An  additional category  of operators  on 16-bit variables is &,
! (also |), and ~ (also \ and ?) denoting AND, OR and ONE's complement
NOT, respectively. These have the same precedence as their  equivalent
boolean operators  and accept  any type  of operand  with a  size <= 2
bytes.

7.8.1 	OPERATORS

7.8.1.1	The Operator Not

<logical not operator> ::= NOT |  ~  |  \  |  ?

	~ (synonyms \ and ?) is a NOT operator for non-booleans.


7.8.1.2 Multiplying Operators

<multiplying operator> ::= *  | /  | DIV | MOD | AND | &

	& is an AND operator on non-booleans.








  All Information Presented Here is Proprietary to Digital Research

				 150




7.8.1.3 Adding Operators

<adding operator> ::= +  |  -  |  OR  |  |  |  !

	! (synonym |) is an OR operator on non-booleans.


7.8.1.4		Relational Operators

<relational operators> ::= = | <> | < | <= | > | >= | IN


7.8.2	FUNCTION DESIGNATORS

<function designator> ::= <function identifier>   |
			  <function identifier> ( <parm> {,<parm>} )
<function identifier> ::= <identifier>





































  All Information Presented Here is Proprietary to Digital Research

				 151





7.9	STATEMENTS
	----------

<statement>	       ::= <label> : <unlabelled statement> |
			   <unlabelled statement>
<unlabelled statement> ::= <simple statement>               |
			   <structured statement>
<label>		       ::= <unsigned integer>


7.9.1	SIMPLE STATEMENTS

<simple statement ::= <assignment statement> |
		      <procedure statement>  |
		      <goto statement>       |
		      <empty statement>
<empty statement> ::= <empty>


7.9.1.1 Assignment Statements

<assignment statement> ::= <variable> := <expression> |
			   <function identifier> := <expression>

      To the list of exceptions to assignment compatibility in  Jensen
and Wirth add:

	1) Expressions of type CHAR may be assigned to variables
	   of type STRING.

	2) Variables of type CHAR and literal characters may
	   be assigned to variables of type BYTE.


7.9.1.2 Procedure Statements

<procedure statement> ::= <procedure identifier> ( <parm> {,<parm>}) |
			  <procedure identifier>
<procedure identifier>::= <identifier>
<parm>		      ::= <Procedure identifier> |
			  <function identifier>  |
			  <expression>           |
			  <variable>


7.9.1.3 Goto Statements

<goto statement> ::= goto <label>





  All Information Presented Here is Proprietary to Digital Research

				 153




      Goto  out  of  a  recursive  procedure  or  out of a sequence of
recursive calls is not supported.


7.9.2	STRUCTURED STATEMENTS

<structured statement> ::= <repetitive statment>   |
			   <conditional statement> |
			   <compound statement>    |
			   <with statement>


7.9.2.1 Compound Statments

<compound statement> ::= BEGIN <statement> {,<statement>} END







































  All Information Presented Here is Proprietary to Digital Research

				 154




7.9.2.2 Conditional Statments

<conditional statement> ::= <case statement>
			    <if statement>


7.9.2.2.1  If Statements

<if statement> ::= IF <expression> THEN <statement> ELSE <statement> |
		   IF <expression> THEN <statement>


7.9.2.2.2  Case Statements

<case statement> ::= CASE <expression> OF
		     <case list> {;<case list>}
		     {ELSE <statement>;}
		     END
<case list>	 ::= <label list> : <statement> |
		     <empty>
<label list>	 ::= <case label> {,<case label>}
<case label>	 ::= <non-real short scalar constant>

      Pascal/MT+ implements an ELSE  clause on the case  statement. In
addition, if the selecting expression  does not match any of  the case
selectors, the program  flow will "drop  through" the case  statement.
This is different  than the standard  which says this  condition is an
error.

	Example:

		CASE CH OF
		  'A' : WRITELN('A');
		  'Q' : WRITELN('Q');	(* optional semicolon *)
		  ELSE
			WRITELN('NOT A OR Q')
		END


7.9.2.3 Repetitive Statements

<repetitive statement> ::= <repeat statement> |
			   <while statement>  |
			   <for statement>












  All Information Presented Here is Proprietary to Digital Research

				 155




7.9.2.3.1  While Statements

<while statement> ::= WHILE <expression> DO <statement>



7.9.2.3.2  Repeat Statements

<repeat statement> ::= REPEAT <statement> {;<statement>} UNTIL <expression>



7.9.2.3.3	For Statements

<for statement>	::= FOR <ctrlvar> := <for list> DO <statement>
<for list>	::= <expression> DOWNTO <expression> |
		    <expression>   TO   <expression>
<ctrlvar> 	::= <variable>



7.9.2.4	With Statements

<with statement>       ::= WITH <record variable list> DO <statment>
<record variable list> ::= <record variable> {,<record variable>}


      The user should note that  the ISO standard differs from  Jensen
and  Wirth  in  that  only  LOCAL  variables  are  allowed as FOR loop
control  variables.  This  prevents  such  programming  errors  as the
inadvertant use of  a GLOBAL variable  as a FOR  control variable when
buried five levels deep in nesting.






















  All Information Presented Here is Proprietary to Digital Research

				 156




7.10	PROCEDURE DECLARATIONS
	----------------------

<procedure declaration>	    ::= EXTERNAL <Procedure heading> |
				<procedure heading> <block>
<block>                     ::= <label declaration part>
				<constant definition part>
				<type definition part>
				<variable declaration part>
				<procfunc declaration part>
				<statement part>

<procedure heading>	    ::= PROCEDURE <identifier> <parmlist>; |
				PROCEDURE <identifier> ;	   |
				PROCEDURE INTERRUPT [ <constant> ]
<parmlist>                  ::= ( <fparm> {,<fparm>} )

<fparm>			    ::= <Procedure heading> |
				<function heading>  |
				VAR <parm group>    |
				<parm group>

<parm group>		    ::= <identifier> {,<identifier>} :
				  <type identifier>             |
				<identifier> {,<identifier>} :
				  <conformant array>

<conformant array>	    ::= VAR ARRAY [ <indxtyp> {;<indxtyp>} OF
				  <conarray2>
<conarray2>		    ::= <type identifier>  |
				<conformant array>

<indxtyp>		    ::= <identifier> .. <identifier> : <ordtypid>

<ordtypid>		    ::= <scalar type identifier>   |
				<subrange type identifier>

<scalar type identifier>    ::= <identifier>

<subrange type identifier>  ::= <identifier>

<label declaration part>    ::= <empty> |
				LABEL <label> {,<label>}

<constant definition part>  ::= <empty> |
				CONST
				  <constant definition>
				  {;<constant definition>}

<type definition part>	    ::= <empty> |
				TYPE
				  <type definition>


  All Information Presented Here is Proprietary to Diqital Research

				 157



				  {;<type definition>} ;

<variable declaration part> ::= <empty>
				VAR
				  <variable declaration>
				  {;<variable declaration>} ;

<procfunc declaration part> ::= {<proc or func> ; }

<proc or func>		    ::= <Procedure declaration> |
				<function declaration>

<statement part>	    ::= <compound statement>



      A  special  procedure  type  is  implemented  in Pascal/MT+, the
interrupt  procedure.  The  user  selects  the vector to be associated
with each interrupt. The procedure is declared as follows:

	PROCEDURE INTERRUPT[vector number] procname;

      The user may refer to Section 3.6 for more information on  using
INTERRUPT procedures.


7.10.1		STANDARD PROCEDURES

      The  following  is  a  list  of  Pascal/MT+  built-in procedures
(except I/O  which are  listed in  Section 7.10.1.1).  See Section 3.4
for parameters and usage. These procedures are predeclared in a  scope
surrounding  the  program.  Therefore,  any  user routines of the same
name will take precedence.

	NEW	 DISPOSE   EXIT		INSERT
	DELETE	 COPY	   CONCAT	FILLCHAR
	MOVELEFT MOVERIGHT CLRBIT	HI
	LO	 SETBIT	   SHL		SHR
	SWAP	 TSTBIT	   LENGTH	POS
	ADDR	 EXIT	   MAXAVAIL	MEMAVAIL
	SIZEOF	 WAIT	   LEAVE


7.10.1.1	File Handling Procedures

      All  standard   file  handling   procedures  are   included.  In
addition the  procedure ASSIGN(f,string)  is added  where f  is a file
and  string  is  a  literal  or  variable  string.  ASSIGN assigns the
external file  name contained  in string  to the  file f.  It is  used






  All Information Presented Here is Proprietary to Digital Research

				 158



preceeding a RESET or REWRITE. See Section 3.4.15 for details.

      Listed below are the names of the file handling procedures:

	GET	PUT	  RESET		REWRITE
	ASSIGN	CLOSE	  CLOSEDEL	PURGE
	OPEN	BLOCKREAD BLOCKWRITE	SEEKWRITE
	CHAIN	PAGE	  SEEKREAD	READ
	GNB	WNB	  IORESULT
	WRITE	READLN 	  WRITELN

      "Local"  (sometimes  called  temporary)  files  in Pascal do not
require  the  use  of  the  ASSIGN  procedure but are implemented in a
different  way  in  each  Pascal  system.  In  Pascal/MT+  a  file  is
assigned  a  system-defined  file  name  of  PASTMP??.$$$. The REWRITE
routine and the linker interact to  allow this to be done. The  linker
fills the data areas with bytes of 00 so that the REWRITE routine  can
see if the file  name is of length  0. In a recursive  environment the
data  area  in  which  files  are  allocated is not initialized at the
beginning of procedure execution. Therefore if the user wishes to  use
a  "temporary"  file  accessed  by  a  local  variable  in a recursive
environment the user  must execute ASSIGN(<file>,'')  before executing
REWRITE.


7.10.1.2	Dynamic Allocation Procedures

	NEW	DISPOSE

      In addition to NEW and  DISPOSE, MEMAVAIL and MAXAVAIL are  also
included.


7.10.1.3	Data Transfer Procedures

	PACK(A,I,Z) UNPACK(Z,A,I)


7.10.2	FORWARD

      Forward procedure  declarations are  implemented in  Pascal/MT+.
It is recommended that this  feature not be used unless  strict Pascal
conformance  is  required.  Due  to  the  nature  of  the  three  pass
compiler, forward declarations are not necessary.


7.10.3	CONFORMANT ARRAYS

      The  user  should  note  that  the  ISO  standard  has added the
CONFORMANT  ARRAY  SCHEMA  for  passing  arrays  of similar structure,
i.e.,  same  number  of  dimensions,  compatible  index type, and same
element type, but different upper  and lower bounds. The user  may now
pass, for example, an array dimensioned as 1_10 and an array 2..50  to
a procedure which is expecting an array as a parameter.

  All Information Presented Here is Proprietary to Digital Research

				 159




The user  defines the  array as  a VAR  parameter (failure  to do this
generates error 154:  'actual parameter must  be a variable'),  and in
the process of  declaring the array,  the user also  defines variables
to hold  the upper  and lower  bound of  the array.  These upper-  and
lower-bound items  are filled  in at  RUN-TIME by  the generated code.
The user should note that in order to pass arrays in this manner,  the
index type must  be compatible with  the type of  the conformant array
bounds.

      Below is an example of  passing two arrays to a  procedure which
displays the contents of the arrays on the file OUTPUT:

PROGRAM DEMOCON;

TYPE
  NATURAL = 0..MAXINT; (* FOR USE IN CONFORMANT ARRAY DECLARATION *)

VAR
  Al : ARRAY [l..10] OF INTEGER;
  A2 : ARRAY [2..20] OF INTEGER;

PROCEDURE DISPLAYIT (

    VAR AR1 : ARRAY [LOWBOUND..HIBOUND:NATURAL] OF INTEGER

		    );
(* THIS DECLARATION DEFINES THREE VARIABLES:

	AR1	: THE PASSED ARRAY
	LOWBOUND: THE LOWER BOUND OF AR1 (PASSED AT RUN-TIME)
	HIBOUND	: THE UPPER BOUND OF AR1 (PASSED AT RUN-TIME)

*)

VAR
  I : NATURAL;
(* COMPATIBLE WITH THE INDEX TYPE OF THE CONFORMANT ARRAY *)

BEGIN
  FOR I := LOWBOUND TO HIBOUND DO
    WRITELN('INPUT ARRAY[',I,']=',AR1[I])
END;

BEGIN (* MAIN PROGRAM *)

	DISPLAYIT(Al);	(* CALL DISPLAYIT AND PASS Al EXPLICITLY AND
			   1 AND 10 IMPLICITLY *)
	DISPLAYIT(A2)	(* CALL DISPLAYIT AND PASS A2 EXPLICITLY AND
			   2 AND 20 IMPLICITLY *)
END.




  All Information Presented Here is Proprietary to Digital Research

				 160




7.11	FUNCTION DECLARATIONS

<function decl>   ::= EXTERNAL <function heading> |
		      <function heading> <block>

<functon heading> ::= FUNCTION <identifier><parmlist>:<result type>; |
		      FUNCTION <identifier> : <result type>

<result type>	  ::= <type identifier>



7.11.1	STANDARD FUNCTIONS

      Listed below are the names of the standard functions supported:

	ABS	    SQR		SIN	    COS		SHORT
	EXP	    LN		SQRT	    ARCTAN *
	ODD	    TRUNC	ROUND	    ORD
	WRD	    CHR		SUCC	    PRED
	EOLN	    EOF		IORESULT    MEMAVAIL
	MAXAVAIL    ADDR	SIZEOF	    POS
	LENGTH	    LENGTH	LONG 	    ULONG

	* for input which is less than 0, ARCTAN returns values
	in the 4th quadrant.


7.11.1.1	Arithmetic Functions


7.11.1.2	Predicates


7.11.1.3	Transfer Functions

      WRD(x) : The  value x (a  variable or expression)  is treated as
the WORD (unsigned integer) value of x.

Other transfer functions are as defined in standard Pascal.



7.11.1.4	Further Standard Functions

File handling:	(F is a file variable. See files in appendix.)

PUT(F) GET(F) RESET(F) REWRITE(F) PAGE(F) EOF(F) EOLN(F)



  All Information Presented Here is Proprietary to Digital Research

				 161





      Because the  CP/M file  structure does  not store  the number of
valid bytes which are present in the last sector, EOF does not  return
true on NON-TEXT files until all of the last sector is read. The  user
must check a dummy final record or save in a separate file the  number
of records contained in the file.

Dynamic Allocation: (Tn is a variant record selector, P is a pointer)

NEW(P) NEW(P,Tl,T2,...,Tn) DISPOSE(P) DISPOSE(P,Tl,T2,...,Tn)

Data Transfer Procedures: (see page 106 of Jensen and Wirth
			   for a more complete description)
PACK(A,I,Z) UNPACK(Z,A,I)

Arithmetic functions:

ABS(X) OR ABS(I)	- special returns the type of its argument
SQR(X) OR SQR(I)	- if passed integer returns integer, etc.

THE FOLLOWING ARE AVAILABLE ONLY IN FLOATING POINT IN PASCAL/MT+
AND NOT BCD:
SIN(X) COS(X) ARCTAN(X) EXP(X) LN(X) SQRT(X)

Transfer functions: (SC is a non-real short scalar)

Implemented at compile-time and generate no code:
ODD(SC) : BOOLEAN ORD(SC) : INTEGER CHR(SC) : CHAR WRD(SC) : WORD

Implemented at run-time and do generate code:

SUCC(<any scalar type except real>) PRED(<any scalar type except
real>)






















  All Information Presented Here is Proprietary to Digital Research

				 162




7.12	INPUT AND OUTPUT
	----------------

      Pascal/MT+  supports  all  standard  Pascal  I/O  facilities. In
addition  to  the  standard  I/O  facilities,  Pascal/MT+  provides  a
mechanism  by  which  Pascal/MT+  programmers  can  write  their   own
character level I/O  drivers in Pascal/MT+.  This facility allows  the
ROM-based program to be system independent and allows the user to  use
the  input  and  output  format  conversion routines with strings, I/O
ports, etc. See Section 3.7  for more information on using  redirected
I/O.


7.12.1	THE PROCEDURE READ

      Reading into subranges is  implemented but no range  checking is
performed, even with range checking turned on.


7.12.2	THE PROCEDURE READLN

<readcall>	 ::= <read or readln> {( {<filevar> ,} {<varlist>} )}

<read or readln> ::= READ | READLN

<filevar> 	 ::= <variable>

<varlist>	 ::= <variable> [,<variable>]


      With variables of type string, only READLN may be used.  Reading
after EOF is  undefined. This usually  results in causing  the program
to stop executing in unpredictable ways.


7.12.3	THE PROCEDURE WRITE


7.12.4	THE PROCEDURE WRITELN

<writecall>	   ::=<write or writeln>I(I<filevar>,Ilexpriistl)I

<write or writeln> ::= WRITE | WRITELN

<exprlist>	   ::= <wexpr> {,<wexpr>}

<wexpr>		   ::= <expression> {:<width expr> {:<dec expr>}}

<width expr>	   ::= <expression>

<dec expr>	   ::= <expression>


  All Information Presented Here is Proprietary to Digital Research

				 163




      You may  not use  functions which  perform input  or output as a
parameter  to  a  WRITE  or  WRITELN  statement.  These include access
routines  such  as  GNB.  The  file  pointers  become  modified by the
reading routines causing the output to be done to the input file.

      The Pascal/MT+  system does  not support  writing a  single line
feed  character  CON:  due  to  the  manner  in  which  CP/M   handles
end-of-line on console and disk files.  If you desire to write a  line
feed use the TRM: device.

      Data  written  using  WRITE  or  WRITELN  may  be formatted. The
format, presented  above, allows  a field  width (<width  expr>) and a
decimal place (<dec expr>)  specification in the write-statement.  The
field width is the number of  spaces this item is to occupy  including
decimal points,  signs, and  exponential notations.  The decimal place
number (used  only with  real numbers)  tells the  output routine  how
many places  to the  right of  the decimal  place are  to be used. All
data items are right justified in the field.

      The  real  numbers  default  output   format  is  to  write   in
exponential notation  with five  digits to  the right  of the  decimal
place  and  12  spaces  in  the  field  width. If the number cannot be
expressed within  the field  width specified  the output  is always in
exponential notation.


7.12.5 ADDITIONAL PROCEDURES

	See Section 7.10.1.1.

      WORD input  and output  is not  performed via  the standard READ
and WRITE  procedures. Two  new procedures  are READHEX  and WRITEHEX.
These allow Hex I/O on variables of any one- or two-byte type such  as
integer, char, byte subrange, enumerated, or word. See the section  in
Chapter 3.4 on Pascal/MT+ extensions.



















  All Information Presented Here is Proprietary to Digital Research

				 164




7.13 	PROGRAMS
	--------

<program>	  ::= <program heading> <block> . |
		      <module heading>
		      	<label declaration part>
		      	<constant definition part>
		      	<type definition part>
		      	<variable declaration part>
		      	<procfunc declaration part>
		      	MODEND .

<program heading> ::= PROGRAM <identifier> {( <prog parms> )};

<module heading>  ::= MODULE <identifier> ;

<prog parms>	  ::= <identifier> {,<identifier>}

      Identical to the standard with the addition of modules. See
      Chapter 3.


































  All Information Presented Here is Proprietary to Digital Research

				 165


























































  All Information Presented Here is Proprietary to Digital Research

				 166




		   APPENDIX A: PASCAL/MT+ FILE I/O
		  --------------------------------

      The most frequently asked questions about Pascal/MT+ pertain  to
files and how to  use them. This appendix  is in response to  requests
for more  information. Because  working from  a simple  example is the
most effective way in which to understand a concept, we have  included
program samples  for each  area of  file handling  and text describing
the features implemented in that program.

    o  The first section defines the terms that are used such
       as 'file,' 'window variable,' and 'TEXT.'

    o  The second section shows how to use all of the file
       operation procedures with examples. These include
       ASSIGN, RESET, REWRITE, sequential file access procedures,
       CLOSE, etc.

    o  The third section defines Pascal TEXT files. Sample
       programs demonstrates the use of built-in boolean functions
       EOLN and EOLF, READLN, WRITELN, formatted I/O, and
       writing to the printer.

    o  The fourth section describes random file access methods.

    o  Section 5 presents a sample program on redirected I/O
       which demonstrates reading and writing numbers to and
       from a string.

    o  Alternative file access methods implemented
       in Pascal/MT+ are described in Section 6. This includes
       high speed input and output.

    o  Section 7 presents some less frequently used file operations.




















  All Information Presented Here is Proprietary to Digital Research

				 167




1.	DEFINITIONS
	-----------

      The terms and  definitions included here  are arranged to  build
up the  concepts of  files as  you read  through. If  you are  already
familiar  with  Pascal  files,  then  continue  to  Section  2 on file
operations in Pascal/MT+.

FILE

      A file is  data arranged in  logical, equal-sized elements  very
much like  an open-ended  array accessed  via a  pointer. The size and
arrangement of the data  is controlled by the  user in his program.  A
file  is  generally  stored  on  a  secondary  storage medium. For the
purpose of this  documentation, secondary storage  is assumed to  be a
disk. You may write data to a file or read data from a file using  the
file operation procedures provided  with Pascal/MT+. This data  in the
file may be accessed sequentially (record 1 accessed before record  2,
record 2  is accessed  before record  3, etc),  or randomly (record 3,
then record 1, then record 2 , etc. in any order).

FILENAME

      The filename is  the name of  the file on  disk. It is  the name
displayed  in  the  directory  listing  of  the  storage  medium.   In
Pascal/MT+ the  filename is  represented in  a program  by a STRING (a
dynamic sequence  of ASCII  characters). For  example, 'B:TEST.DAT' is
the filename in  literal string format  for the file  located on drive
'B' with the name of 'TEST' and the extension of 'DAT'.

TYPE

      The  type  of  a  file  defines  the  size  and  format  of  the
individual file  elements, the  smallest accessable  units of  a file.
For example, a  file that is  of type INTEGER  (2 8-bit bytes)  may be
visualized as:


















  All Information Presented Here is Proprietary to Digital Research

				 168




	+--------+--------+--------+--------+--------+--------+
	|00001000|00000000|00100001|00000000|00000001|00000000|
	+--------+--------+--------+--------+--------+--------+
	|   record 0	  |	record 	1   |	record 2      |

This file contains the integers 8, 33, and 1 (stored inverted in  this
sample).  The  smallest  retrievable  element  is  two  bytes. See the
explanations of untyped files or byte files if you want to treat  this
file  differently  than  a  file  of  integers.  Files  may  be of the
standard Pascal scalar types:  BOOLEAN, INTEGER, CHAR, or  REAL. Files
may also be of the  structured types STRING, arrays, and  records. The
predefined type TEXT is used  for ASCII files. Text files  are similar
to  FILE  of  CHAR  except  that  they  are subdivided into lines, and
numbers  written  to  them  are   converted  to  ASCII  (and  may   be
formatted), and  numbers read  from them  are converted  to binary.  A
line  is  a  sequence  of  characters  terminated  by  an  end of line
character which is usually  a carriage return/line feed.  Also, unlike
FILE of  CHAR, TEXT  files will  accept PACKED  ARRAY[l..N] OF CHAR or
ARRAY[l..N]  OF CHAR  (writing an UNPACKED ARRAY is not ISO standard),
and  STRINGS  as  data.  A  boolean  value  is  converted to the ASCII
sequence 'TRUE' or 'FALSE' on write  but the reverse is not true.  For
further  explanations  on  typed  and  text  files, see the operations
section.

      A non-ISO standard concept regarding files is the UNTYPED  file.
This is used for fast block input and output (entire sectors are  read
or written)  regardless of  the kind  of data  contained in  the file.
Further information on untyped files may be found in Section 6.




FILE INFORMATION BLOCK (FIB)

      The  FIB  contains  information   necessary  for  the   run-time
routines to perform file operations on a disk file. The filename,  the
type of  the file,  the access  type (read  or write), end-of-file and
end-of-line flags, and  a disk buffer  (the size of  one physical disk
sector)  are  among  the  kinds  of  information  kept in the FIB. See
FIBDEF.LIB on  your distribution  disk for  a complete  description of
the FIB.  Also, the  previous definition  of a  file variable contains
further information on the FIB.




WINDOW VARIABLE OR WINDOW POINTER

      The window variable is a buffer  the size of a file element  and
is located just past  the FIB in Pascal/MT+.  A way to think  of it is
that it moves along the file and acts as a 'window' to the element  of
the  file  which  is  to  be  read  or written. For this reason, it is
considered a  pointer to  the  file  element  being  accessed.  It  is

  All Information Presented Here is Proprietary to Digital Research

				 169




denoted as 'F^' where F is the  name of a file variable. To read  from
a  file,  the  element  which  is  accessable  is  moved to the window
variable. To write to  a file, the data  must be transferred from  the
window variable to the file.




FILE VARIABLE

      The file variable  consists of a  FIB and a  window variable. It
is the actual data item allocated by the compiler and referenced in  a
Pascal program. An  example will clarify  what a file  variable is, as
well as what the FIB and window variable are. The statement, 'VAR F  :
FILE OF INTEGER;' ,  causes the compiler to  create a file variable  F
with its  own FIB  in the  data area  and its  own window  variable (2
bytes) to  hold a  16-bit integer.  The window  variable is denoted by
F^. Suppose 'I' is  an integer in the  same program and has  the value
2. Suppose  also that  the file  already contains  the value  1 in the
first element as below:

+--------+--------+--------+--------+--------+--------+
|00000001|00000000|        |        |        |        |
+--------+--------+--------+--------+--------+--------+
      +----------++--------+--------+
      | FIB	 ||00000010|00000000|	window variable
      +----------++--------+--------+

To write  the contents  of I  to the  file, the  window variable  must
contain 2 (F^ :=  I puts the contents  of I into the  window variable)
and be  'positioned' over  the second  element of  the file. Given the
command PUT(F) described  in the operations  section, the number  2 is
written to the file.

END OF FILE

      Files  must  be  terminated  in  some  fashion.  Most  operating
systems use  a control  character to  denote the  end of  a file. When
this character is read by  the system, the standard built-in  function
EOF returns true. There are some conditions, e.g., when the data  does
not fill  up the  last sector  in the  file, in  which the  end of the
valid data comes before the  operating system signals an end  of file.
In this  case, monitoring  EOF does  not give  you a  true when  it is
actually the end of the data. The user must use a dummy record as  the
last record or save the number of records in a separate file.









  All Information Presented Here is Proprietary to Digital Research

				 170




2.	FUNDAMENTAL FILE OPERATIONS
	---------------------------

      Sample programs  and explanations  demonstrate the  use of  file
operation procedures in Pascal/MT+. You will see how to open,  create,
read, write,  delete, close,  and randomly  access files. Demonstrated
also are the use  of typed and text  files; the file status  functions
IORESULT, EOF, and EOLN; and how to assign to a window variable.

      Figure  1  lists  a  program  named  WRITE_READ_FILE_DEMO  which
creates a  typed file  on disk,  writes data  to the  file, closes the
file, then  re-opens the  file to  read the  data back. The procedures
used to perform these are ASSIGN, REWRITE, RESET, IORESULT, PUT,  GET,
and CLOSE. WRITE is used to  display the results on the terminal.  The
output  work  is  done  in  WRITEFILE  and  the  input work is done in
READFILE. Creating, opening, and closing the file is done in the  main
body of the program.

      The WRITELN  statements on  lines 37,  43, 46,  and 49 write the
string passed to them to  the default OUTPUT file (the  console). This
procedure and READLN  are discussed later  in this section  under TEXT
files.

      First  note  the  form  of  the  declaration  of  OUTFILE. It is
declared to be of  type CHFILE which is  defined as a FILE  OF CHAR in
the TYPE  declaration section  (lines 3  and 4).  This is done because
the  file  is  passed  as  a  parameter  to the WRITEFILE and READFILE
routines and a parameter list cannot declare a new type. For  example,
the following parameter declaration is illegal in Pascal because  only
type identifiers are allowed in a parameter list:

	PROCEDURE WRITEFILE( VAR F : FILE OF CHAR);






















  All Information Presented Here is Proprietary to Digital Research

				 171


 1	0	PROGRAM WRITE-READ-FILE-DEMO;
 2	0
 3	0	TYPE
 4	1	  CHFILE = FILE OF CHAR;
 5	1	VAR
 6	1	  OUTFILE: CHFILE;
 7	1	  RESULT: INTEGER;
 8	1	  FILENAME:	STRING[16]
 9	1
10	1	  PROCEDURE	WRITEFILE( VAR F : CHFILE);
11	1	  VAR CH: CHAR;
12	2	  BEGIN
13	2	    FOR CH := '0' TO '9' DO
14	2	      BEGIN
15	3		F^ := CHR(CHR(I + ORD('0'));l
16	3		PUT(F)
17	3	      END;
18	2	  END;
19	1
20	1	  PROCEDURE	READFILE( VAR F : CHFILE);
21	1	  VAR I: INTEGER;
22	2	      CH: CHAR;
23	2	  BEGIN
24	2	    FOR I := 0 TO 9 DO
25	2	      BEGIN
26	3		CH := F^;
27	3		GET(F);
28	3		WRITELN(CH);
29	3	      END;
30	2	  END;
31	1
32	1	BEGIN
33	1	  FILENAME := 'TEST.DAT';
34	1	  ASSIGN(OUTFILE,FILENAME);
35	1	  REWRITE(OUTFILE);
36	1	  IF IORESULT = 255 THEN
37	1	    WRITELN('Error creating ',FILENAME)
38	1	  ELSE
39	1	    BEGIN
40	2		WRITEFILE(OUTFILE);
41	2		CLOSE(OUTFILE,RESULT);
42	2		IF RESULT = 255 THEN
43	2		  WRITELN('Error closing ',FILENAME)
44	2		ELSE
45	2		  BEGIN
46	3		    WRITELN('Successful close of ',FILENAME);
47	3		    RESET(OUTFILE);
48	3		    IF IORESULT = 255 THEN
49	3			WRITELN('Cannot open ',FILENAME)
50	3		    ELSE
51	3			READFILE(OUTFILE)
52	3		  END;
53	2	    END;
54	1	END.
		Figure 1 : File Input and Output.

  All Information Presented Here is Proprietary to Digital Research

				 172






PROCEDURE ASSIGN(VAR F : FILE VARIABLE; STR : STRING);

Purpose: Associate the file variable  F with an external file  on disk
named in STR.

      ASSIGN is the  first file operation  to be executed  in line 34.
This procedure associates a  file variable (OUTFILE) with  an external
file on a  disk given in  FILENAME ( in  this case it  is 'TEST.DAT').
The string passed  to ASSIGN is  placed into the  FIB and the  name is
interpreted. After executing the  ASSIGN procedure, the file  variable
passed to  the ASSIGN  procedure is  always associated  with the  disk
file named in the name  parameter until, or unless, another  ASSIGN is
done to the file variable.

PROCEDURE REWRITE(VAR F : FILE VARIABLE);

Purpose: Create  a file  on disk  using the  name in  the FIB  (either
filled  in  by  the  ASSIGN  statement  previously  or null (if null a
temporary file is created).

      The  REWRITE  procedure  is  called  in  line  35  of  Figure 1.
Executing this procedure causes the  creation of a file with  the name
contained in the FIB of F. Any existing files by that name are deleted
so NEVER use REWRITE  on a file which  contains useable data. In  this
example, the file on disk will  be named 'TEST.DAT' and is located  on
the default  disk (because  no other  disk was  specified in  the file
name string passed to ASSIGN).

      If no previous ASSIGN had been performed, the name field of  the
FIB  is  empty  and  a  temporary  file  is  created  with  the   name
'PASTMPOO.$$$.' Temporaray  files are  generally used  for scratch pad
memory and data  which is not  needed after execution  of the program.
The digits at the last two positions in the name are used to give each
temporary file a unique name so the user may have up to 100  temporary
files.

      The  EOF  function  and  the  EOLN  function return true because
OUTFILE  is  an  output  file.  OUTFILE  is  open  only  for   writing
sequentially and is ready to receive data into its first element.  See
the text  with Figure  4 for  considerations on  random access after a
REWRITE. If  the operation  is not  successful, the  IORESULT function
returns a 255 in this case (see line 36).

FUNCTION IORESULT : INTEGER;

Purpose	:  Return  the  integer   value  indicating  status  of   file
operation.





  All Information Presented Here is Proprietary to Digital Research

				 173




      The value  of this  function is  set after  any input  or output
operation and  may be  checked at  any time.  Note in  Figure 1  it is
called after each file operation in  lines 36, 42, and 46. It  is used
here to stop the program if a file operation did not work as  planned.
Note that you cannot 'WRITE (IORESULT)'  because IORESULT is reset  to
0 after  each I/O  operation. The  meaning of  the values  returned by
IORESULT is presented in Chapter 3.

PROCEDURE PUT(VAR F : FILE VARIABLE);

Purpose  :  Transfer  the  contents  of the window variable associated
with F to the next available record in the file.

      Procedure WRITEFILE,  beginning on  line 9  of Figure  1, writes
the characters '0' to '9' to  the TEST.DAT file. The PUT procedure  is
what  causes  the  data  to  be  written  to  the  file. Always before
executing a PUT, an  assignment is made to  the window variable as  in
line 15. Following is a diagram of what is occurring :

+--------+
|00110000| Window variable after assignment (line 15) and CH
+--------+ is equal to '0'.
+--------+--------+--------+--------+--------+--------+
|        |        |        |        |        |        | ..........
+--------+--------+--------+--------+--------+--------+
File before any PUT statement is executed.
         +--------+
	 |00110000|	Window variable after PUT in line 16.
         +--------+
+--------+--------+--------+--------+--------+--------+
|00110000|        |        |        |        |        | ..........
+--------+--------+--------+--------+--------+--------+ File after the
first PUT is executed in the FOR loop in Figure 1, lines 13 through
17.

PROCEDURE WRITE;
PROCEDURE WRITE(expression,...,,expression);
PROCEDURE WRITE(VAR F:FILE VARIABLE,expression,....,expression);

Purpose  :  Shorthand  for  'F^   :=  data;  PUT(F);'  Also   performs
conversions to ASCII on numbers when F is a TEXT file.

      Expression  includes  contents  of  variables,  strings,   array
elements,  constants,  and  expressions.  When  a file variable is not
specified, the  default OUTPUT  file is  assumed. The  WRITE procedure
does exactly the same  operations on the file  as lines 15 and  16. It
executes an  assignment followed  by a  PUT and  is merely a shorthand







  All Information Presented Here is Proprietary to Digital Research

				 174




version. GET and  PUT are provided  because the ISO  standard requires
them and in some  versions of Pascal, such  as UCSD Pascal, WRITE  can
only be used on TEXT files.

PROCEDURE CLOSE(VAR F : FILE VARIABLE; RESULT : INTEGER);

Purpose : Flush the  buffer in the FIB  associated with F so  all data
is written to the disk.

      The  next  statement  to   be  executed  after  returning   from
WRITEFILE  is  line  41,  where  the  file  is  closed.  CLOSE must be
executed to  assure that  the data  written to  'TEST.DAT' is actually
saved on  the disk.  Up until  this point  the data  is written to the
buffer in memory and now must be saved by flushing the buffer.  RESULT
is the value returned by  the operating system indicating whether  the
close is successful. It has the same value as IORESULT returns. It  is
included  as  a  parameter  to  maintain  compatibility  with previous
versions of  the compiler.  In this  program a  value of  255 means an
error closing the file, any other value indicates success.

PROCEDURE RESET(VAR F : FILE VARIABLE);

Purpose : Open  an existing file  for reading. The  window variable is
moved to the  beginning of the  file. For random  access, the file  is
open for reading and writing.

      After checking  RESULT, the  procedure RESET  is called  in line
47. RESET  opens an  existing file  for reading  and resets the window
variable  to  the  beginning  of  the  file.  F- is assigned the first
element of F. If  F is already open,  RESET calls CLOSE. EOF  and EOLN
return  FALSE.  If  a  RESET  is  done  on a file that does not exist,
IORESULT  contains  a  255.  All  other  values  of  IORESULT indicate
success.  In  the  sample  program  OUTFILE  is  opened  by  the RESET
procedure so that it may be read.  Below is a diagram of the file  and
window variable  after the  RESET is  executed in  line 47.  Note that
with  non-console  typed  files  such  as OUTFILE, the procedure RESET
does an  initial GET  which moves  the first  element of  the file (in
this case the ASCII value for the number 0) into the window variable.

+--------+
|00110000| Window variable (OUTFILE^) after RESET (line 47).
+--------+
+--------+--------+--------+--------+--------+--------+
|00110000|00110001|00110010|00110011|00110100|00110101| ....
+--------+--------+--------+--------+--------+--------+









  All Information Presented Here is Proprietary to Digital Research

				 175




The initial GET  is not performed  on console files  or untyped files.
The reason  for this  is that  the user  would always  have to  type a
character  before  his  /  her  program  could execute because the GET
procedure is waiting for a character.

PROCEDURE GET(VAR F : FILE VARIABLE);

Purpose : Transfer the currently accessible record to the window
variable and advance the window variable.

      After  checking   that  the   RESET  procedure   is  successful,
procedure READFILE  is called  in line  51. This  procedure reads each
element  of  the  file  passed  to  it  (in this case the element is a
character) and writes that element  to the screen. READFILE begins  on
line 20. The work is done in the FOR loop of lines 24 through 29.

      The GET procedure  advances the window  variable by one  element
and  moves  the  contents  of  the  file  pointed  to  into the window
variable. If no  next element exists  EOF becomes TRUE.  See Section 3
on TEXT  files for  more details  on GET  and TEXT  files. The diagram
below describes what is happening within the FOR loop on lines 26  and
27 the first time through the loop.

+--------+
|00110000| Window variable (OUTFILE) after line 26
+--------+
+--------+--------+--------+--------+--------+--------+
|00110000|00110001|00110010|00110011|00110100|00110101| ...
+--------+--------+--------+--------+--------+--------+
After executing line 26, CH contains the ASCII for 0 (00110000).
After executing line 27, the window variable is advanced.

	 +--------+
	 |00110001| Window variable after GET in line 27.
	 +--------+
+--------+--------+--------+--------+--------+--------+
|00110000|00110001|00110010|00110011|00110100|00110101| ....
+--------+--------+--------+--------+--------+--------+

Line 28 writes the contents of CH to the default output file which  is
the console.  Procedure READFILE  displays the  characters '0' through
'9' in a  column on the  console. Calling CLOSE  after a RESET  is not
necessary in the  sequential case because  the file already  exists on
the disk and has not been  altered in any way. If OUTFILE  is accessed
randomly, a CLOSE might be necessary.









  All Information Presented Here is Proprietary to Digital Research

				 176




PROCEDURE READ(data, data,...,data);
PROCEDURE READ(VAR F : FILE VARIABLE , data, data, ..., data);

Purpose:  When  used  with  non-console  files  execute  'data  := F^;
GET(F);'  for  each  data  item  read.  When  used  with console files
execute  'GET(F);  data  :=  F^;'.  If  F is not specified the default
INPUT file is used. See the  section on TEXT files for information  on
conversions.

      The READ procedure  is exactly the  same as an  assignment and a
call to GET. If READ is  used rather than GET in the  current example,
the FOR loop body would look like this:

FOR I := 0 TO 9 DO
  BEGIN
    READ(CH);
    WRITELN(CH)
  END;

      Reading past  end-of-file on  console input  results in crashing
the system.

































  All Information Presented Here is Proprietary to Digital Research

				 177




3.	TEXT FILES
	----------

DEFINITION

      A TEXT file  is a file  of ASCII characters  which is subdivided
into  lines.  A  line  is  a  sequence  of  characters terminated by a
nonprintable end-of-line  indicator, usually  a carriage  return and a
line  feed-character.  It  is  similar  to  a file of CHAR except that
automatic conversion of numbers is  performed when they are read  from
and written to the  file. Also, variables of  type STRING may be  read
from  a  text  file  and  BOOLEANs,  STRINGs, and PACKED ARRAYs may be
written to text files.  Access to a TEXT  file is via GET  and PUT for
character I/O (which do not do conversions), READ and WRITE which have
been defined in earlier in this section, and READLN and WRITELN  which
are used in Figure 2 and defined in this section.

      The format of a TEXT file in memory is a FIB and a 1-byte window
variable. On  disk, the  file looks  as this  sample below  in which a
carriage return is represented by '>', linefeed by '/' and end of file
by '#'.

+-------------------------------------------------------------+
This is a line>/This is the next line>/This is the last line>/#
+-------------------------------------------------------------+


FUNCTION EOLN : BOOLEAN;
FUNCTION EOLN(VAR F : TEXT) BOOLEAN;

Purpose: Indicate the  state of the  file by returning  true only when
the window variable  is over the  end-of-line character. When  no file
is specified the default INPUT file is assumed.

      This is a  function which returns  true on disk  text files when
the last valid  character on a  line is read  using a READ  statement.
Because the sequence of statements for  a READ (on  non-console files)
is 'CH  := F^;  GET(F);', the  window variable  is positioned over the
end-of-line character  immediately after  the last  character is read.
Thus,  EOLN  returns  TRUE  on  NON-CONSOLE  TEXT  files when the last
character is read. Also, a BLANK character is returned instead of  the
end-of-line  character.  The  above  sequence  is  reversed on CONSOLE
files (READ is an initial call  to GET followed by an assignment  from
the window  variable) .  For this  reason, using  CONSOLE files,  EOLN
will  return  true  after  the  carriage  return  /  line feed is read
instead of  after the  last character  as in  disk files.  A blank  is
still returned in the character.







  All Information Presented Here is Proprietary to Digital Research

				 178




FUNCTION EOF : BOOLEAN;
FUNCTION EOF(VAR F : FILE) : BOOLEAN;

Purpose: Indicate the state of a file by returning true only when  the
window variable  is over  an end-of-file  character. When  no file  is
specified the default INPUT file is assumed.

      EOF  is  a  function  which  returns  true  when the end-of-file
character is read. It  is similar to EOLN  in that the last  character
read will set EOF to true  on NON-CONSOLE files. On CONSOLE files  EOF
is true only when the  end-of-file indicator is entered. Reading  past
end-of-file on console files is not supported (the system can  crash).
Reading past the  end of the  file on disk  files is not  supported. A
blank is returned by the window variable when EOF is true. Also,  note
that on non-text files EOF may not become true at the end of the valid
data as the data may not fill up the entire last sector of the file.

      Figure 2 is a  program which simply writes  data to a text  file
and reads it back to be displayed on the output device. The  procedure
WRITEDATA actually writes to the TEXT file and the procedure  READDATA
retrieves the information stored in  the file. The program is  divided
into a main body and  two procedures to demonstrate the  usefulness of
breaking up  code into  blocks which  perform certain  functions. This
makes code much easier to read and debug.

      The file  is declared  in line  3. Note  that the declaration is
NOT 'VAR F :  FILE of TEXT'. TEXT  is treated as a  special version of
FILE of  CHAR, so  FILE of  TEXT translates  to FILE  of FILE  of CHAR
(nonsensical).

      The  program  begins  execution  on  line  25 with a call to the
ASSIGN  procedure.  Lines  25  through  29  create  a  TEXT file named
TEXT.TST on the  logged in drive.  If the file  creation is successful
then the sample data is initialized  in lines 31 and 32 followed  by a
call to the WRITEDATA routine in line 33.  WRTITEDATA uses the WRITELN
procedure which is only used with TEXT files.

PROCEDURE WRITE;
PROCEDURE WRITELN;
PROCEDURE WRITELN(expr,expr .... expr);
PROCEDURE WRITELN(F);
PROCEDURE WRITELN(F,expr,expr,...expr);

Purpose: Put  the data  into the  file associated  with F,  ending the
output with  and end-of-line  character. If  no file  is specified the
expressions  are  written  to  the  OUTPUT  file.  A  writeln  with no
expressions merely outputs  a carriage return  / line feed.  The WRITE
procedure is redefined as a  conversion rather than a replacement  for
PUT.





  All Information Presented Here is Proprietary to Digital Research

				 179




      This procedure writes the data  passed to it to the  file named,
placing an end-of-line character after the last item of data  written.
If no file  is named it  is written to  the default OUTPUT  file. Data
may  be  literal  and  named  constants,  integers,  reals, subranges,
enumerated, booleans,  strings, and  packed arrays  of characters, but
may not be structured types such as records. Numeric data is converted
to ASCII and strings are  treated as arrays of characters  (the length
byte is not written to the file).


Formatted Output

      In Figure 2 three lines which make up the body of WRITEDATA  (9,
10, and 11) do  the actual file output.  Line 9 sends the  contents of
the variable string S followed by a carriage return / line feed to the
TEXT file  F. Line  10 formats  the contents  of I  in a field of four
spaces and sends this formatted output to the file F. The real  number
literal in line 11 is formatted  into a field of nine spaces,  four of
which must be to the right of the decimal place. This formatted number
is then written to the file  F. The field format may be  specified for
any data type. For non-real numbers only the field width is specified,
not the number of  places after the decimal  point. The data is  right
justified in the field. If a number is larger than the 6.5 significant
digits can represent,  the output is  always expressed in  exponential
notation. Also, if the field width is too small to express the  number
it  is  written  in  exponential  notation. For further information on
formatting consult a Pascal textbook and experiment.

      The body of the WRITEDATA  procedure could have been written  in
the following manner with the same results.

		WRITELN (F, S) ;
		WRITELN(F,I:4, 45.6789 : 9 : 4);

      Control returns to the main body  of the program and line 34  is
executed. If the CLOSE is successful,  the RESET in line 39 opens  the
file F (which is still associated with 'TEXT.TXT' on the disk), moving
the window variable to the  beginning in preparation for reading  data
from the file F. Following  a successful RESET the procedure  READDATA
is  called  to  read  back  the  information  placed in 'TEXT.TST' and
display it on the console.













  All Information Presented Here is Proprietary to Digital Research

				 180




Stmt	Nest	Source Statement

	1	0	PROGRAM TEXTIO_DEMO;
	2	0
	3	0	VAR F : TEXT;
	4	1	    I :	INTEGER;
	5	1	    S :	STRING;
	6	1
	7	1	  PROCEDURE WRITEDATA;
	8	1	  BEGIN
	9	2	    WRITELN(F,S);
	10	2	    WRITE (F, I: 4) ;
	11	2	    WRITELN(F,45.6789:9:4);
	12	2	  END;
	13	1
	14	1	  PROCEDURE READDATA;
	15	1	  VAR R : REAL;
	16	2	  BEGIN
	17	2	    READLN(F,S);
	18	2	    READ(F,I);
	19	2	    READ(F,R);
	20	2	    WRITELN(S);
	21	2	    WRITELN(I:4,' ',R:9:4);
	22	2	  END;
	23	1
	24	1	BEGIN
	25	1	  ASSIGN(F,'TEXT.TST');
	26	1	  REWRITE(F);
	27	1	  IF IORESULT = 255 THEN
	28	1	    WRITELN('Error creating')
	29	1	  ELSE
	30	1	    BEGIN
	31	2	      I := 35;
	32	2	      S	:= 'THIS IS A STRING';
	33	2	      WRITEDATA;
	34	2	      CLOSE(F,I);
	35	2	      IF IORESULT = 255 THEN
	36	2		WRITELN('Error closing')
	37	2	      ELSE
	38	2		BEGIN
	39	3		  RESET(F);
	40	3		  IF IORESULT = 255 THEN
	41	3		    WRITELN('Error opening')
	42	3		  ELSE
	43	3		    READDATA;
	44	3		END;
	45	2	    END;
	46	1	END.
	46	0	--------------------------
	46	0	Normal End of Input Reached

			Figure 2 : Text Files


  All Information Presented Here is Proprietary to Digital Research

				 181




PROCEDURE READ;
PROCEDURE READLN;
PROCEDURE READLN(F);
PROCEDURE READLN( F, variable, variable,...,variable);

Purpose:  Read  from  the  file  associated  with F into the variables
listed. In all  cases, read until  an end-of-line character  is found,
skipping any  unread data,  and advance  to the  beginning of the next
line. READ  redefined to  perform conversion  of reals,  booleans, and
integers.

      READLN,  like  WRITELN,  has  as  parameters  an  optional  file
variable and  any number  of variables  to receive  the data  from the
file. If the file variable is  not specified, input is taken from  the
default INPUT file, the keyboard. The variables in the parameter  list
are the same type  as the data being  read from the file.  However, no
type checking is done so it is up to the user to construct a parameter
list compatible  to the  format of  his /  her file.  Any numbers  are
converted  on  input  but  the  formatting  is  lost.  Numbers must be
separated  from  each  other  and  other  data  types  by a blank or a
carriage return linefeed.

      READLN  recognizes  but  does   not  transmit  the   end-of-line
character.  Its  action  is  to  read  data  until  it  encounters  an
end-of-line and advance  the window variable  to the beginning  of the
next line. The data in 'TEXT.TST' looks like the following:

		THIS IS A STRING>/
			35  45.6789>/#

After reading the string in the first line to read the integer 35  one
must use READ and not READLN. If a READLN were used here, the 35 would
be  read  properly  because  the  first  blank  terminates the number.
However, the window  variable would be  advanced past the  real number
to the end of the file. Then,  if one tries to read the real,  all one
gets is  EOF and  then one  wonders what  happened to  the real number
known to be out there.

      STRINGS  must  always  be  read  with  a READLN because they are
terminated with end-of-line  characters. If the  data to the  file had
been 'THIS IS A STRING 35>/' ,  the value returned for S would be  the
entire line including the ASCII 35.

      Lines 20 and 21 write the data to the console in the same format
as it is contained in the file.









  All Information Presented Here is Proprietary to Digital Research

				 182




      After executing READDATA,  the program is  finished. A CLOSE  is
not necessary since the data in  'TEXT.TST' is not altered in any  way
since the last CLOSE on that file.


Writing to the printer

      Writing  to  the  printer  is  very  simple,  as demonstrated in
Figure 3. A file variable is declared to be of type TEXT as in line  5
of Figure 3. This file variable is ASSIGNed to the printer in line 11.
The filename 'LST: passed to ASSIGN  means that F is to be  associated
with the list device  so that all data  written to F is  routed to the
printer. REWRITE is called to  open the list device for  writing. Note
that a CLOSE is not necessary since the data has already been  written
and  the  buffer  does  not  need  to  be flushed. Lines 23 and 25 use
standard Pascal formatting directives. In line 23, R is to be  written
in a field seven characters long with three digits to the right of the
decimal place.

Stmt	Nest	Source Statement

 1 	0	PROGRAM PRINTER;
 2	0	(* WRITE DATA AND TEXT TO THE PRINTER *)
 3	0
 4	0	VAR
 5	1	  F : TEXT;
 6	1	  I : INTEGER;
 7	1	  S : STRING;
 8	1	  R : REAL;
 9	1
10	1	BEGIN
11	1	  ASSIGN(F,'LST:');
12	1	  REWRITE(F);
13	1	  IF IORESULT = 255 THEN
14	1				WRITELN('Error rewriting file')
15	1	  ELSE
16	1	    BEGIN
17	2	      S := 'THIS LINE IS A STRING';
18	2	      I := 55;
19	2	      R := 3.141563;
20	2	      WRITE(F,S);
21	2	      WRITE(F,I);
22	2	      WRITELN(F);
23	2	      WRITELN (F, R: 7: 3)
24	2	      WRITE (F, I, R) ;
25	2	      WRITE(F,I:4,R:7:3);
26	2	      WRITELN(F);
27	2	      WRITELN(F,'THIS IS THE END.')
28	2	    END
29	2	END.
29	0	--------------------------
29	0	Normal End of Input Reached

	Figure 3 : Writing to a Printer and Number Formatting

  All Information Presented Here is Proprietary to Digital Research

				 183




4.	RANDOM FILE I/O
	---------------

      In this section  the procedures SEEKREAD  and SEEKWRITE will  be
discussed  along with the Pascal/MT+ intrinsics for randomly accessing
a  file.  The  sample  program  RANDOM  DEMO  shows  the  use of these
procedures,  plus the declaration,  creation and opening of a file  to
be accessed randomly. Also shown in this program are one use of  sets,
the ELSE on  the CASE statement,  the EXIT statement,  WRITE, WRITELN,
READ, and READLN.

      A random file  is merely a  typed Pascal file  which is accessed
via the  random access  procedures SEEKREAD  and SEEKWRITE.  Thus, any
file may be a random file;  there is no special syntax when  declaring
a file  which makes  it a  random instead  of a  sequential file.  The
random access routines allow the  user to specify the relative  record
number desired. This is different  than sequential access in that  the
user must access record 0 before  record 1, etc. Up to 65,536  records
may be randomly accessed.

      The sample program in Figure  4a and 4b, RANDOM DEMO,  shows the
use of  random file  access. This  program either  creates or  uses an
existing  file  of  records  of  type  PERSON. Each record in the file
contains two strings;  the name of  a person and  the address of  that
person. It loops on lines 69 through 80 allowing the user to read  any
existing record via the procedure  READRECS or to write to  any record
via  the  procedure  WRITERECS.  Let us  examine  the main body of the
program first and then see  what the  procedures READRECS,  WRITERECS,
and ERRCHK are doing.

      Program  execution  begins  on  line  59  by  writing  a  prompt
questioning the user if he wants to create a file or open an  existing
file. The file is created if desired and in any case the file is RESET
in line 68. This  brings up an important  point. With random files,  a
file that has been RESET may  either be read from (using SEEKREAD)  or
written to (using  SEEKWRITE). This is  unlike sequential files  which
may only be read after a RESET. Also, a new file created using REWRITE
may be accessed via SEEKREAD after data has been written to the  file.
The repeat loop allows the process of reading and writing to  continue
until stopped with a 'Q'  input. Suppose the response to  the question
R)ead  W)rite  or Q)uit  is 'R'.  Procedure READRECS  is called  which
uses SEEKREAD to read a record.












  All Information Presented Here is Proprietary to Digital Research

				 184




Stmt	Nest	Source Statement

 1	0	PROGRAM RANDOM_DEMO;
 2	0
 3	0	TYPE
 4	1	  PERSON = RECORD
 5	1		     NAME : STRING;
 6	1		     ADDRESS : STRING;
 7	1		   END;
 8	1
 9	1	VAR
10	1	  BF : FILE OF PERSON;
11	1	  S  : STRING;
12	1	  I  : INTEGER;
13	1	  ERROR : BOOLEAN;
14	1	  CH : CHAR;
15	1
16	1	EXTERNAL PROCEDURE @HLT;
17	1
18	1	PROCEDURE ERRCHK;
19	1	BEGIN
20	2	  ERROR:= TRUE; (*DEFAULT*)
21	2	  CASE IORESULT OF
22	2	    0 : BEGIN WRITELN('Successful'); ERROR := FALSE END;
23	3	    1 : WRITELN('Reading unwritten data');
24	3	    2 : WRITELN('CP/M error');
25	3	    3 : WRITELN('Seeking to unwritten extent');
26	3	    4 : WRITELN('CP/M error');
27	3	    5 : WRITELN('Seek past physical end of disk')
28	3	  ELSE
29	3	    WRITELN('Unrecognizable error code')
30	3	  END;
31	2	END;
32	1
33	1	PROCEDURE READRECS;
34	1	BEGIN
35	2	  WRITE('Record number? ');
36	2	  READLN(I);
37	2	  SEEKREAD(BF,I);
38	2	  ERRCHK;
39	2	  IF ERROR THEN
40	2	    EXIT;
41	2	  WRITELN(BF^.NAME,'/',BF^.ADDRESS);
42	2	END;
43	1

	      Figure 4-a : Random file input and output







  All Information Presented Here is Proprietary to Digital Research

				 185




Stmt		Nest	Source Statement

44	1	PROCEDURE WRITERECS;
45	1	BEGIN
46	2	  WRITE('Name?');
47	2	  READLN(S);
48	2	  BF^.NAME := S;
49	2	  WRITE('Address?');
50	2	  READLN(S);
51	2	  BF^.ADDRESS := S;
52	2	  WRITE('Record number? ');
53	2	  READLN(I);
54	2	  SEEKWRITE(BF,I);
55	2	  ERRCHK;
56	2	END;
57	1
58	1	BEGIN
59	1	  WRITE('Create file?');
60	1	  READLN(S);
61	1	  IF S[l] IN ['Y','y'] THEN
62	1	    BEGIN
63	2	      ASSIGN(BF,'B:BIG.FIL');
64	2	      REWRITE(BF);
65	1	      CLOSE(BF,I);
66	2	    END;
67	1	  ASSIGN(BF,'B:BIG.FIL');
68	1	  RESET(BF);
69	1	  REPEAT
70	2	    WRITE('R)ead, W)rite or Q)uit? ');
71	2	    READ(CH);
72	2	    WRITELN;
73	2	    CASE CH OF
74	2		'R','r':	READRECS;
75	3		'w','w':	WRITERECS;
76	3		'Q','q':	@HLT
77	3	    ELSE
78	3		WRITELN('Enter R, W or Q only')
79	3	    END
80	2	  UNTIL FALSE;
81	1	END.
81	0	---------------------------
81	0	Normal End of Input Reached

	      Figure 4-b : Random File Input and Output










  All Information Presented Here is Proprietary to Digital Research

				 186




PROCEDURE SEEKREAD(VAR F  : FILE; RECORD-NUMBER  : 0..largest word  in
system);

Purpose :  Transfer the  contents of  the record  designated in RECORD
NUMBER to the window variable for F. Uses CP/M function call 33.

      The file  parameter, F,  is any  typed file  which has been made
accessible via an ASSIGN followed by a RESET or a REWRITE (if there is
data to be read). RECORD NUMBER is the relative record desired,  where
0 is the record at the beginning of the file. The record is  retrieved
(if it exists) and assigned to the window variable buffer. If it  does
not exist because a record past  the end of the file is  requested, an
error value  is returned  in IORESULT.  In this  program note that the
procedure ERRCHK checks IORESULT for errors based on the CP/M system.

      The  procedure  READRECS  asks  for  a  record number, reads the
record from the file, and writes it directly from the window  variable
to the  screen if  the record  exists. Line  37 contains  the call  to
SEEKREAD giving it the filename and the record number. From this it is
obvious that if record 0 and 2 contain data, an attempt to read record
1 will be allowed, although record 1 does not contain any data.  Thus,
the user must be careful  about accessing unwritten records which  the
system is not able to detect as an error. The information retrieved is
written in line 41. Note how the window buffer is used as a pointer as
if it  were declared  like a  pointer to  a record  type. If  the user
desires to save the data elsewhere, an assignment to a data  structure
of the same type as the file (in this case type PERSON) is made.



		VAR	TEMP : PERSON; ......
		... TEMP := BF^;




      Note that once  a file has  been accessed via  a SEEKREAD (or  a
SEEKWRITE) it must be CLOSED and reopened in order to access with  the
sequential methods listed earlier (GET and READ, PUT and WRITE).




PROCEDURE SEEKWRITE (VAR F :ANY-FILE; RECORD-NUMBER: 0.. largest word)

Purpose : Put  the contents of  the window variable  associated with F
into  the  disk  file  at  the  relative record location designated in
RECORD-NUMBER. Uses CP/M function call 34.






  All Information Presented Here is Proprietary to Digital Research

				 187




      SEEKWRITE  is  used  in  procedure  WRITERECS  which is found on
lines 44 through 56. WRITERECS asks the user for the data required  to
fill a record of type PERSON (lines 46 through 51), asks the user  for
the record number to be written (lines 52 and 53), and calls SEEKWRITE
(line 54) to write the data to the disk. ERRCHK is called in line  55.
Assignment is made to the window variable in lines 48 and 51. The file
looks like the diagram below after  writing data to records 0, 1,  and
3.



+---------------+
|  Name....     |
|  Address..... |  representation of PERSON record.
+---------------+

+---------------+---------------+---------------+---------------+
|  Gremlin B. H.| Fred Gnome	| Unwritten.dat | MT Monster    |
| Nottingham	| Under the Hill| Garbage.....	| Front Cover   |
+---------------+---------------+---------------+---------------+
   Record 0	  Record 1	   Record 2	   Record 3

      Records  within  a  file  written  with  SEEKWRITE  are   stored
contiguously on the disk, regardless of the number of sectors occupied
by a record. Because this is  true a file created using SEEKWRITE  may
be accessed after a CLOSE and RESET using sequential access methods.




























  All Information Presented Here is Proprietary to Digital Research

				 188




5.	REDIRECTED I/O
	--------------

      Redirected I/O is an alternative to using the get-character  and
put-character routines in the run-time package and is useful when  the
regular  CP/M  I/O  is  not  desired.  Also,  this feature is good for
converting numbers into strings and strings into numbers. In fact, the
sample program in figure 5 demonstrates this application.

      The put-character routine, WIR, begins  on line 8. It writes  to
a global string,  CONV. GETCH, the  get-character function, begins  on
line 28. This routine gets its character input from the global string,
CONV.

      The  test  program  code  begins  on  line  39,  and  the  first
statements  initialize  the  variables  required  by  WIR  and  GETCH.
CONVERTING is a  boolean which true  when WIR is  writing a number  to
CONV. CONV is initialized to the empty string so its length byte is 0.
The test variable, I, is assigned  2438 in line 42 and written  to the
console via the regular WRITELN statement in line 43.

      Line  44  is  the  first  instance  of  redirected  I/O  in this
program. The address of WIR is  passed to the WRITELN routine so  that
WIR  is  used  instead  of  the  put-character routine in the run time
package. The  number, I,  is converted  by the  run-time routines into
characters which are passed to  WIR for "output" to the  string, CONV.
In this  way the  contents of  I is  converted to  a string.  WIR must
always be called with  a WRITELN as it  uses the carriage return  as a
signal that the number is complete.

      WIR checks first whether the character it receives is a linefeed
($0A) and exits  if it is.  Line 12 checks  to see if  conversion of a
number has already begun. If so,  and the character is not a  carriage
return ($0D) which indicates the end of the number, the new  character
is concatenated onto  the existing characters  in CONV in  line 14. If
this is  a new  number, CONV  is set  to the  null string  in line 19.
Again, the check is  made for a carriage  return in the case  where no
characters are passed.  If a character  is passed, it  is concatenated
onto the string. CONVERTING is set to TRUE.

      After returning from WIR, 'I' is  assigned 0 in line 45 so  that
when the GETCH routine is called it is clear that the old value, 2438,
is "read" from CONV. Line 47 writes out the contents of CONV which  by
this point is 2438.

      Finally, the  read procedure  uses GETCH  in line  48 to  read a
number into I from CONV. GETCH continues to return characters until it
empties CONV, as indicated in line 30. Line 32 shows the assignment to
GETCH of the first character  in CONV. This character is  deleted from
CONV in line 33 so a new first character is returned the next call  to
GETCH. When the string is empty, a blank is returned, which the system
requires to indicate the end of a read.


  All Information Presented Here is Proprietary to Digital Research

				 189


Stmt	Nest	Source Statement

 1	0	PROGRAM CONV_DEMO;
 2	0
 3	0	VAR
 4	1	  I : INTEGER;
 5	1	  CONV : STRING;
 6	1	  CONVERTING : BOOLEAN;
 7	1
 8	1	PROCEDURE WIR(CH : CHAR)
 9	1	BEGIN
10	2	  IF CH = CHR($0A) THEN	(*Done, ignore linefeed *)
11	2	    EXIT;
12	2	  IF CONVERTING THEN
13	2	    IF CH <> CHR($0D) THEN (*Not at end of string *)
14	2	      CONV :=CONCAT(CONV,CH)
15	2	    ELSE
16	2	      CONVERTING := FALSE  (*reached end-done*)
17	2	  ELSE			   (*First call, new string *)
18	2	    BEGIN
19	3	      CONV := '';
20	3	      IF CH <> CHR($0D) THEN
21	3		  BEGIN
22	4		    CONV := CONCAT(CONV,CH);
23	4		    CONVERTING := TRUE
24	4		  END
25	4	    END;
26	2	END;
27	1
28	1	FUNCTION GETCH:CHAR;
29	1	BEGIN
30	2	  IF LENGTH(CONV) > 0 THEN    (*Something left to convert*)
31	2	    BEGIN
32	3		GETCH := CONV[1];
33	3		DELETE(CONV,1,1);
34	3	    END
35	3	  ELSE
36	2	    GETCH := ' ';	      (*Return blank-No more chars*)
37	2	END;
38	1
39	1	BEGIN			      (* Main Program *)
40	1	  CONVERTING	:= FALSE;
41	1	  CONV := '';
42	1	  I := 2438;
43	1	  WRITELN('I=',I);
44	1	  WRITELN([ADDR(WIR)],I);     (* Field width may be given *)
45	1	  I := 0;
46	1	  WRITELN('I=',I);
47	1	  WRITELN('CONV=',CONV);
48	1	  READ([ADDR(GETCH)],I);      (* READLN may not be used *)
49	1	  WRITELN('I=',I);
50	1	END.
50	0	---------------------------
50	0	Normal End of Input Reached
		      Figure 5: Redirected I/0

  All Information Presented Here is Proprietary to Digital Research

				 190




6.	FILE INPUT AND OUTPUT METHODS
	-----------------------------

Figures 6  through 9  are four  different implementations  of a simple
file transfer  procedure named  TRANSFER. Figure  10 is  the main body
which  calls  the  transfer  routine.  Following  Figure 10 is a table
listing code and data size and execution speed for the programs listed
in Figures 6 through 9.

      The BLOCKREAD and BLOCKWRITE  implementation is shown in  Figure
6. Here untyped files use a large 2K buffer to transfer data.

PROCEDURE BLOCKREAD(F : FILE VARIABLE; BUFFER : ANYTYPE;
VAR IOR : INTEGER; SZ, RB : INTEGER);

Purpose : Transfer the data  to the BUFFER variable for  the specified
number  of  bytes  (SZ)  starting  at  the relative block number (RB).
Direct CP/M disk access using function call 20.

      On CP/M  the RB  parameter is  in the  range -1-64K.  The extent
is calculated and opened, if  necessary, when RB is greater  than 127.
If RB is -1, sequential access is assumed and the next 128-byte sector
is read. The code in Figure 6 could always use -1 for RB and  function
in the same manner as it does now.

      SZ is the number  of bytes to be  read. It must be  at least 128
bytes and may no larger than the buffer. Lines 25 and 28 show that the
SZ parameter may be calculated using the SIZEOF function.



PROCEDURE BLOCKWRITE(F : FILE VARIABLE; BUFFER	ANYTYPE;
	VAR IOR : INTEGER; SZ,RB 	INTEGER);

Purpose : Transfer user data from  the BUFFER to the file F,  starting
at relative block number (RB)  for SZ bytes. Provides CP/M  level disk
access  using  function  call  21.  As  in  BLOCKREAD,  when  RB is -1
sequential disk access is assumed.

      The variable 'I' is used for the RB parameter. In line 29 it  is
incremented by 16 which is the  number of bytes in BUF, 2048,  divided
by the number  of bytes in  a sector, 128.  This means that  each time
through the loop 16 sectors of  128 bytes each are read into  BUF from
the source file and written to the the destination file.

      RESULT is 0 if all data is read and nonzero if no data exists in
the next record. The program as it is written works when transfering a
file whose size is an even multiple of 2K. For example, if the  source
file    is    9K    bytes    in    size,    the    final    1K   would





  All Information Presented Here is Proprietary to Digital Research

				 191




not be written because RESULT  returns a non-zero after the  BLOCKREAD
in line 25. Using 128-byte  buffer would guarantee transfering all  of
the data.

      Figure  7  shows  the  same  file transfer procedure implemented
using the GNB  and WNB routines.  This method appears  to transfer one
byte at a time but actually  uses a 2K buffer for reading  and writing
bytes. Therefore, it is much faster than GET and PUT.



FUNCTION GNB(F : FILE OF PAOC) : CHAR;

Purpose: PAOC  is any  type which  is a  packed array  of CHAR  in the
optimum range of 128..4095. Provide high speed byte level access to F.

      Because the  file used  by GNB  is a  file of  a Packed Array of
Character  type  there  are  boundary  conditions on CP/M-80 which may
cause confusion. On these  systems the run-time support  routines read
the data from the  disk file into a  one sector buffer in  the FIB and
then transfer the data  into the window variable.  If the data in  the
file is not an even multiple of the window variable size then the  EOF
flag in the FIB will be set "early" even though there is valid data in
the window variable. The GNB routine will properly return the  partial
window variable data  and then begin  returning hex FF  bytes when the
data is totally exhausted. If processing a TEXT file on CP/M (8080  or
8086) using GNB one can look  for a hex 1A character to  determine the
true end of data.

FUNCTION WNB(F : FILE OF CHAR, CH : CHAR) : BOOLEAN;
Purpose: Write to  F one byte  at a time.  Returns a true  value if an
error occurs while writing that byte.

      On  CP/M  :  If  the  window  variable  is  not full when a file
accessed  with  WNB  is  CLOSEd,  the  entire window variable is still
written to the  file and the  file may contain  "garbage" data at  the
end. It is suggested that you always "flush" the window variable using
either hex 1A if the file is an  ascii file, or hex FF if the file  is
not ascii, prior to closing the file.

      Figure 8  presents the  file transfer  procedure using  SEEKREAD
and SEEKWRITE.  Because these  two routines  have been  discussed in a
previous section, this Figure  is present only for  comparisions. Note
that as in BLOCKI/0, if the last portion of data from the source  file
does not  fill the  sector, in  this case  the 2K  bytes which  is the
window  variable  for  file  variable  A,  then  IORESULT  returns a 1
indicating end-of-file. However, the final portion of code which  does
not  fill up  the 2K  buffer is never written to the destination file.






  All Information Presented Here is Proprietary to Digital Research

				 192




      Figure 9 transfers files using GET and PUT which is much  slower
than any of these buffered  methods. See previous sections on  the use
of GET and PUT.

Stmt	Nest	Source Statement

1	0	PROGRAM FILE_TRANSFER;
2	0
3	0	(*---------------------------------------------------------
4	0	(* Transfer file a to file b using BLOCKREAD and BLOCKWRITE
5	0	(*---------------------------------------------------------
6	0
7	0	CONST
8	1	  BUFSZ = 2047;
9	1	TYPE
	10	  PAOC : ARRAY[l..BUFSZ] OF CHAR;
11	1	  FYLE : FILE;
12	1
13	1	VAR
14	1	  A,B : FYLE;
15	1	  NAME	STRING;
16	1	  BUF : PAOC;
17	1
18	1	PROCEDURE TRANSFER(VAR SRC: FYLE; VAR DEST FYLE);
19	1	VAR
20	2	  RESULT,I : INTEGER;
21	2	  QUIT : BOOLEAN;
22	2	BEGIN
23	2	  I := 0;
24	2	  REPEAT
25	3	    BLOCKREAD(SRC,BUF,RESULT,SIZEOF(BUF),I);
26	3	    IF RESULT = 0 THEN
27	3	      BEGIN
28	4		BLOCKWRITE(DEST,BUF,RESULT,SIZEOF(BUF),I);
29	4		I := I + SIZEOF(BUF) DIV 128
30	4	      END
31	4	    ELSE
32	3	      QUIT := TRUE;
33	3	  UNTIL QUIT;
34	2	  CLOSE(DEST,RESULT);
35	2	  IF RESULT = 255 THEN
36	2	    WRITELN('Error closing destination file')
37	2	END;
38	1		(* MAIN PROGRAM IN FIGURE 10 *)

	Figure 6: File Transfer with BLOCKREAD and BLOCKWRITE






  All Information Presented Here is Proprietary to Digital Research

				 193




Stmt		Nest	Source Statement

 1	0	PROGRAM FILE_TRANSFER;
 2	0
 3	0	(*---------------------------------------------
 4	0	(* Transfer file a to file b using GNB and WNB
 5	0	(*---------------------------------------------
 6	0
 7	0	CONST
 8	1	  BUFSZ = 2047;
 9	1	TYPE
10	1	  PAOC = ARRAY[l..BUFSZ] OF CHAR;
11	1	  TFILE = FILE OF PAOC;
12	1	  CHFILE = FILE OF CHAR;
13	1	VAR
14	1	  A : TFILE;
15	1	  B : CHFILE;
16	1	  NAME : STRING;
17	1
18	1	PROCEDURE TRANSFER(VAR SRC: TFILE; VAR DEST CHFILE);
19	1	VAR
20	2	  CH : CHAR;
21	2	  RESULT : INTEGER;
22	2	  ABORT : BOOLEAN;
23	2	BEGIN
24	2	  ABORT := FALSE;
25	2	  WHILE (NOT EOF(SRC)) AND (NOT ABORT) DO
26	2	    BEGIN
27	3	      CH := GNB(SRC);
28	3	      IF WNB(DEST,CH) THEN
29	3		BEGIN
30	4		  WRITELN('Error writing character');
31	4		  ABORT := TRUE;
32	4		END;
33	3	    END;
34	2	    CLOSE(DEST,RESULT);
35	2	    IF RESULT = 255 THEN
36	2	      WRITELN('Error closing')
37	2	END;
38	1		(* MAIN PROGRAM IN FIGURE 10 *)

	      Figure 7: File Transfer with GNB and WNB












  All Information Presented Here is Proprietary to Digital Research

				 194




Stmt	Nest	Source Statement

 1	0	PROGRAM FILE_TRANSFER;
 2	0
 3	0	(*-------------------------------------------------------*)
 4	0	(* Transfer file a to file b using SEEKREAD and SEEKWRITE*)
 5	0	(*-------------------------------------------------------*)
 6	0
 7	0	CONST
 8	1	  BUFSZ = 2047;
 9	1
10	1	TYPE
11	1	  PAOC = ARRAY[O..BUFSZ] OF CHAR;
12	1	  TFILE = FILE OF PAOC;
13	1	  CHFILE = FILE OF PAOC;
14	1	VAR
15	1	  A : TFILE;
16	1	  B : TFILE;
17	1	  NAME : STRING;
18	1	PROCEDURE TRANSFER(VAR SRC: TFILE; VAR DEST	TFILE);
19	1	VAR
20	2	  CH : CHAR;
21	2	  RESULT2,RESULT,I : INTEGER;
22	2	  ABORT : BOOLEAN;
23	2	BEGIN
24	2	  CH := W;
25	2	  RESULT := 0;
26	2	  I := 0;
27	2	  WHILE RESULT <> 1 DO
28	2	    BEGIN
29	3	      SEEKREAD(SRC, I)
30	3	      RESULT := IORESULT;
31	3	      IF RESULT	= 0 THEN
32	3		BEGIN
33	4		  DEST^	:= SRC^;
34	4		  SEEKWRITE (DEST, I)
35	4		END;
36	3	      I = I + 1;
37	3	    END;
38	2
39	2	  CLOSE (DEST, RESULT)
40	2	  IF RESULT = 255 THEN
41	2	    WRITELN('Error closing destination file')
42	2	END;
43	1		(* MAIN PROGRAM IN FIGURE 10 *)

	 Figure 8: File Transfer with SEEKREAD and SEEKWRITE







  All Information Presented Here is Proprietary to Digital Research

				 195




Stmt	Nest	Source Statement
1	0	PROGRAM FILE_TRANSFER;
2	0
3	0	(*-------------------------------------------------*)
4	0	(* Transfer file a to file b using GET and PUT     *)
5	0	(*-------------------------------------------------*)
6	0
7	0	TYPE
8	1	  CHFILE = FILE OF CHAR;
9	1	VAR
10	1	  A,B	: CHFILE;
11	1	  NAME	: STRING;
12	1
13	1	PROCEDURE TRANSFER(VAR SRC: CHFILE; VAR DEST CHFILE);
14	1	VAR
15	2	  RESULT : INTEGER;
16	2	BEGIN
17	2	  WHILE NOT EOF(SRC) DO
18	2	    BEGIN
19	3	      DEST^ := SRC^;
20	3	      PUT(DEST);
21	3	      GET(SRC);
22	3	    END;
23	2
24	2	  CLOSE(DEST,RESULT);
25	2	  IF RESULT = 255 THEN
26	2	    WRITELN('Error closing destination file')
27	2	END;
28	1		(* MAIN PROGRAM IN FIGURE 10 *)

	      Figure 9: File Transfer with GET and PUT























    All Information Presented Here is Proprietary to Digital Research

				 196






BEGIN
  WRITE('Source? ');
  READLN (NAME) ;
  ASSIGN(A,NAME);
  RESET(A);
  IF IORESULT = 255 THEN
    BEGIN
      WRITELN('Cannot open ',NAME);
      EXIT
    END;

  WRITE('Destination? ');
  READLN(NAME);
  ASSIGN(B,NAME);
  REWRITE(B);
  IF IORESULT = 255 THEN
    BEGIN
      WRITELN('Cannot open ',NAME);
      EXIT
    END;

  TRANSFER(A,B)
END.

Figure 10: File Transfer: Main Program Body for Figures 6 Through 9

      The  following  table  shows  code  and  data size and execution
speed of the above file transfer procedures on a 4MHz Z80 with no wait
states, and a single density, single sided, 8" floppy disk. Sizes  are
in decimal bytes and the speed is in seconds. The file transferred was
8K bytes exactly. These numbers will not be identical for all releases
of the compiler, so if your version is not the same size and speed  as
that listed  there is  nothing amiss.  The data  demonstrates only the
size and speed differences among four file access methods.

Transfer Method	    BLOCK I/O	GNB/WNB	    SEEK I/O	GET/PUT

Compiled Code	    520		519	    530		477
Compiled Data	    2532	2534	    4584	482
Total Code	    7317	7161	    9243	6764
Total Data	    3576	3577	    5697	1494
Total Size	    10893	10738	    14940	8258
Speed		    7.8		18.4	    8.6		35.1









  All Information Presented Here is Proprietary to Digital Research

				 197




7.	MISCELANEOUS FILE ROUTINES
	--------------------------

      A sample program is not  provided for the following routines  as
the use of these is  obvious or duplicates a previously  described set
of file routines.

PROCEDURE OPEN (F: FILE VARIABLE, TITLE : STRING; VAR RESULT INTEGER);
Purpose : Identical to the sequence 'ASSIGN(F,TITLE) ; RESET(F);'

PROCEDURE CLOSEDEL (F : FILE VARIABLE; VAR RESULT : INTEGER);
Purpose  :  Close  file  F  and  delete it. Used with temporary files.
Exactly the same as CLOSE followed by PURGE.

PROCEDURE PURGE (F : FILE VARIABLE);
Purpose : Delete the file associated  with F from the disk. An  ASSIGN
must be executed sometime  before the call to  PURGE so that the  file
control block for F  contains the name of  the file to be  deleted. On
some operating  systems other  than CP/M  (80 or  86) the  file may be
required to be closed before this procedure can function properly.  In
this case CLOSEDEL is a useful procedure.

































  All Information Presented Here is Proprietary to Digital Research

				 198



		     APPENDIX B: ERROR MESSAGES
		     --------------------------

Recursion stack overflow: evaluation stack collision with symbol table
correct by reducing symbol table size, simplifying expressions.

 1: Error in simple type
    Self-explanatory.

 2: Identifier expected
    Self-explanatory.

 3: 'PROGRAM' expected
    Self-explanatory

 4: ')' expected
    Self-explanatory

 5: ': ' expected
    Possibly a = used in a VAR declaration

 6: Illegal symbol (possibly missing ';' on line above)
    Symbol encountered is not allowed in the syntax at this point.

 7: Error in parameter list
    Syntactic error in parameter list declaration.

 8: 'OF' expected
    Self-explanatory.

 9: '(' expected
    Self-explanatory.

10: Error in type
    Syntactic error in TYPE declaration.

11: '[' expected
    Self-explanatory.

12: ']' expected
    Self-explanatory.

13: 'END' expected
    All procedures, functions, and blocks of statements
    must have an 'END'. Check for mismatched BEGIN/ENDs.

14: '; ' expected (possibly on line above)
    Statement separator required here.

15: Integer expected
    Self-explanatory.

16: '=' expected
    Possibly a : used in a TYPE or CONST declaration.

  All Information Presented Here is Proprietary to Digital Research

				 199



 17: 'BEGIN' expected
     Self-explanatory.

 18: Error in declaration part
     Typically an illegal backward reference to a type in
     a pointer declaration.

 19: error in <field-list>
     Syntactic error in a record declaration

 20: '.' expected
     Self-explanatory.

 21: '*' expected
     Self-explanatory.

 50: Error in constant
     Syntactic error in a literal constant, also when using recursion
     and improperly using INP and OUT.

 51: ':=' expected
     Self-explanatory.

 52: 'THEN' expected
     Self-explanatory.

 53: 'UNTIL' expected
     Can result from mismatched begin/end sequences

 54: 'DO' expected
     Syntactic error.

  55: 'TO' or 'DOWNTO' expected in FOR statement
     Self-explanatory.

 56: 'IF' expected
     Self-explanatory.

 57: 'FILE' expected
     Probably an error in a TYPE declaration.

 58: Error in <factor> (bad expression)
     Syntactic error in expression at factor level.

 59: Error in variable
     Syntactic error in expression at variable level.

 99: MODEND expected
     Each MODULE must end with MODEND.

101: Identifier declared twice
     Name already in visible symbol table.

102: Low bound exceeds high bound

  All Information Presented Here is Proprietary to Digital Research

				 200



     For subranges the lower bound must be <= high bound.

103: Identifier is not of the appropriate class
     A variable name used as a type, or a type used
     as a variable, etc. can cause this error.

104: Undeclared identifier
     The specified identifier is not in the visible
     symbol table.

105: sign not allowed
     Signs are not allowed on non-integer/non-real constants.

106: Number expected
     This error can often come from making the compiler totally
     confused in an expression as it checks for numbers after all
     other possibilities have been exhausted.

107: Incompatible subrange types
     (e.g. 'A'..'Z' is not compatible with 0..9).

108: File not allowed here
     File comparison and assignment is not allowed.

109: Type must not be real
     Self-explanatory.

110: <tagfield> type must be scalar or subrange
     Self-explanatory.

111: Incompatible with <tagfield> part
     Selector in a CASE-variant record is not
     compatible with the <tagfield> type

112: Index type must not be real
     An array may not be declared with real dimensions

113: Index type must be a scalar or a subrange
     Self-explanatory.

114: Base type must not be real
     Base type of a set may be scalar or subrange.

115: Base type must be a scalar or a subrange
     Self-explanatory.

116: Error in type of standard procedure parameter
     Self-explanatory.

117: Unsatisified forward reference
     A forwardly declared pointer was never defined.

118: Forward reference type identifier in variable declaration
     The user has attempted to declare a variable as a pointer

  All Information Presented Here is Proprietary to Digital Research

				 201




     to a type which has not yet been declared.

119: Re-specified params not OK for a forward declared procedure
     Self-explanatory.

120: Function result type must be scalar, subrange or pointer
     A function has been declared with a string or other non-scalar
     type as its value. This is not allowed.

121: File value parameter not allowed
     Files must be passed as VAR parameters.

122: A forward declared function's result type can't be re-specified
     Self-explanatory.

123: Missing result type in function declaration
     Self-explanatory.

125: Error in type of standard procedure parameter
     This is often caused by not having the parameters in the
     proper order for built-in procedures or by attempting to read/write
     pointers, enumerated types, etc.

126: Number of parameters does not agree with declaration
     Self-explanatory.

127: Illegal parameter substitution
     Type of parameter does not exactly match the
     corresponding formal parameter.

128: Result type does not agree with declaration
     When assigning to a function result, the types must be compatible.

129: Type conflict of operands
     Self-explanatory.

130: Expression is not of set type
     Self-explanatory.

131: Tests on equality allowed only
     Occurs when comparing sets for other than equality.

133: File comparison not allowed
     File control blocks may not be compared as they contain multiple
     fields which are not available to the user.

134: Illegal type of operand(s)
     The operands do not match those required for this operator.

135: Type of operand must be boolean
     The operands to AND, OR and NOT must be BOOLEAN.

136: Set element type must be scalar or subrange
     Self-explanatory.

 All Information Presented Here is Propriet"ary to Digital Research

				 202



137: Set element types must be compatible
     Self-explanatory.

138: Type of variable is not array
     A subscript has been specified on a non-array variable.

139: Index type is not compatible with the declaration
     Occurs when indexing into an array with the wrong type of
     indexing expression.

140: Type of variable is not record
     Attempting to access a non-record data structure
     with the 'dot' form or the 'with' statement.

141: Type of variable must be file or pointer
     Occurs when an up arrow follows a variable which is not
     of type pointer or file.

142: Illegal parameter solution
     Self-explanatory.

143: Illegal type of loop control variable
     Loop control variables may be only local non-real scalars.

144: Illegal type of expression
     The expression used as a selecting expression in a case
     statement must be a non-real scalar.

145: Type conflict
     Case selector is not the same type as the selecting expression.

146: Assignment of files not allowed
     Self-explanatory.

147: Label type incompatible with selecting expression
     Case selector is not the same type as the selecting expression.

148: Subrange bounds must be scalar
     Self-explanatory.

149: Index type must be integer
     Self-explanatory.

150: Assignment to standard function is not allowed
     Self-explanatory.

151: Assignment to formal function is not allowed
     Self-explanatory.

152: No such field in this record
     Self-explanatory.

153: Type error in read
     Self-explanatory.

  All Information Presented Here is Proprietary to Digital Research

				 203



154: Actual parameter must be a variable
     Occurs when attempting to pass an expression as a VAR parameter.

155: Control variable cannot be formal or non-local
     The control variable in a FOR loop must be LOCAL.

156: Multidefined case label
     Self-explanatory.

157: Too many cases in case statement
     Occurs when jump table generated for case overflows its bounds.

158: No such variant in this record
     Self-explanatory.

159: Real or string tagfields not allowed
     Self-explanatory.

160: Previous declaration was not forward

161: Again forward declared

162: Parameter size must be constant

163: Missing variant in declaration
     Occurs when using NEW/DISPOSE and a variant does not
     exist.

164: Substition of standard proc/func not allowed

165: Multidefined label
     Label more than one statement with same label.

166: Multideclared label
     Declare same label more than once.

167: Undeclared label
     Label on statement has not been declared.

168: Undefined label
     A declared label was not used to label a statement.

169: Error in base set

170: Value parameter expected

171: Standard file was re-declared

172: Undeclared external file

174: Pascal function or procedure expected
     Self-explanatory.

183: External declaration not allowed at this nesting level

  All Information Presented Here is Proprietary to Digital Research

				 204


     Self-explanatory

187: Attempt to open library unsuccessful
     Self-explanatory.

191: No private files
     Files may not be declared other than in the GLOBAL
     variable section of a program or module as they must
     be statically allocated.

193: Not enough room for this operation
     Self-explanatory

194: Comment must appear at top of program

201: Error in real number - digit expected
     Self-explanatory

202: String constant must not exceed source line

203: Integer constant exceeds range
     Range on integer constants are -32768..32767

250: Too many scopes of nested identifiers
     There is a limit of 15 nesting levels at compile-time.
     This includes WITH and procedure ripstina

251: Too many nested procedures or functions
     There is a limit of 15 nesting levels at execution
     time. Also occurs when more than 80 routines in one compiled
     module.

253: Procedure (or program body) too long
     A procedure has generated code which has overflowed
     the internal procedure buffer. Reduce the size of
     the procedure and try again. The limit is target
     machine dependent. Consult the CPU applications note
     for more information.

259: Expression too complicated
     The users expression is too complicated (i.e. too many
     recursive calls needed to compile it). The user should
     reduce the complication using temporary variable

397: Too many FOR or WITH statments in a procedure
     Only 16 FOR and / or WITH statments are allowed in
     a single procedure (in recursive mode only)

398: Implementation restriction
     Normally used for arrays and sets which are too big to
     be manipulated or allocated.

400: Illegal character in text
     A character which is a non-Pascal special character
     was found outside of a quoted string.

  All Information Presented Here is Proprietary to Digital Research

				 205




401: Unexpected end of input
     End. encountered before returning to outer level.

402: Error in writing code file, not enough room
     Self-explanatory.

403: Error in reading include file
     Self-explanatory.

404: Error in writing list file, not enough room
     Self-explanatory.

405: Call not allowed in separate procedure
     Self-explanatory.

406: Include file not legal
     Self-explanatory.

407: Symbol Table Overflow

496: Invalid operand to INLINE
     Usually due to reference which requires address
     calculation at run time.

497: Error in closing code file.
     An error occured when the ERL file was closed.
     Make more room on the destination disk and try again.

999: Compiler confused due to previous errors. Make some
     corrections and try again. It is also possible that while
     your program is syntactically correct it may cause the
     compiler to become confused if semantic errors exist.
     The compiler will abort early with this error number.
     Look carefully at the line on which the compilation halts.




















  All Information Presented Here is Proprietary to Digital Research

				 206




		     APPENDIX C: RESERVED WORDS
		     --------------------------

      The following are the reserved words in Pascal/MT+:

	AND	DOWNTO	FUNCTION  NIL	     PROGRAM	TYPE
	ARRAY	ELSE	GOTO	  NOT	     RECORD	UNTIL
	BEGIN	END	IF	  OF	     REPEAT	VAR
	CONST	FILE	IN	  OR	     SET	WHILE
	CASE	FOR	LABEL	  PACKED     THEN	WITH
	DO	FORWARD	MOD	  PROCEDURE  TO

	Pascal/MT+ also has extended reserved words:

	ABSOLUTE   EXTERNAL







































  All Information Presented Here is Proprietary to Digital Research

				 207



	       APPENDIX D: LANGUAGE SYNTAX DESCRIPTION
	       ---------------------------------------
<letter> ::= A | B | C | D | E | F | G | H | I | J |
	     K | L | M | N | O | P | Q | R | S | T |
	     U | V | W | X | Y | z | a | b | c | d |
	     e | f | g | h | i | j | k | 1 | m | n |
	     n | o | p | q | r | s | t | u | v | w |
	     x | y | z | @

<digit>	 ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
	     A | B | C | D | E | F | {only allowed in HEX numbers}

<special symbol> ::= {reserved words are listed in section 16.2}
	     +  |  -  |  *  |  /  |  =  |  <> |  <  |  >  |
	     <= |  >= |  (  |  )  |  [  |  ]  |  {  |  }  |
	     := |  .  |  ,  |  ;  |  :  |  '  |  ^  |

	     {the following are additional or substitutions:}
	     (. |  .) |  ~  |  \  |  ?  |  !  |  |  |  $  |  &

	     (. is a synonym for [
	     .) is a synonym for ]
	     , and ? are synonyms	(see section 8.1.1)
	     !, and | are synonyms	(see section 8.1.2)
	     &	 			(see section 8.1.3)



<identifier>	::= <letter> {<letter or digit or underscore>}

<letter or digit or underscore> ::= <letter> | <digit> | _

<digit sequence>   ::= 	<digit> {<digit>}

<unsigned integer> ::= $ <digit sequence> |
			 <digit sequence>

<unsigned real>	   ::= <unsigned integer> . <digit sequence> |
		       <unsigned integer> . <digit sequence>
		       E <scale factor>                      |
		       <unsigned integer> E <scale factor>

<unsigned number>  ::= <unsigned integer> | <unsigned real>

<scale factor>	   ::= <unsigned integer> | <sign><unsigned integer>

<sign>		   ::= + | -

<string>	   ::= ' <character> {character>}' | ''

<constant identifier> ::= <identifier>

<constant>	      ::= <unsigned number>           |
			  <sign><unsigned number>     |

  All Information Presented Here is Proprietary to Digital Research

				 209




			  <constant identifier>       |
			  <sign><constant identifier> |
			  <string>

<constant definition> ::= <identifier> = <constant>

<type>		      ::= <simple type>     |
			  <structured type> |
			  <pointer type>

<type definition>     ::= <identifier> = <type>

<simple type>         ::= <scalar type>         |
			  <subrange type>       |
			  <type identifier>

<type identifier>     ::= <identifier>

<scalar type>	      ::= ( <identifier> {,<identifier>})

<subrange type>	      ::= <constant> .. <constant>

<structured type>     ::= <unpacked structured type>	    |
			  PACKED <unpacked structured type>

<unpacked structured type> ::= <array type>  |
			       <record type> |
			       <set type>    |
			       <file type>

<array type>	      ::= <normal array>  |
			  <string array>
<string array>	      ::= STRING <max length>

<max length>	      ::= [ <intconst> ] |
			  <empty>

<intconst>	      ::= <unsigned integer>
			  <int const id>

<int const id>	      ::= <identifier>

<normal array>	      ::= ARRAY [ <index type> ] {,<index type>}] OF
			  <component type>

<index type>	      ::= <simple type>

<component type>      ::= <type>

<record type>	      ::= RECORD <field list> END

<field list>	      ::= <fixed part>                  |
			  <fixed part> ; <variant part> |

  All Information Presented Here is Proprietary to Digital Research

				 210



			  <variant part>

<fixed part>	      ::= <record section> {;<record section>}

<record section>      ::= <field identifier> {,<field identifier>} :
				<type> |
			  <empty>

<variant part>	      ::= CASE <tag field> <type identifier> OF
				<variant> {;<variant>}

<variant>	      ::= <case label list> : (<field list>) |
			  <empty>

<case label list>     ::= <case label> {,<case label>}

<case label>	      ::= <constant>

<tag field>	      ::= <identifier> |
			  <empty>

<set type>	      ::= SET OF <base type>

<base type>	      ::= <simple type>

<file type>	      ::= file {of <type>}

<variable>	      ::= <var>          |
			  <external var> |
			  <absolute var>

<external var>	      ::= EXTERNAL <var>

<absolute var>	      ::= ABSOLUTE [ <constant>	] <var>

<var>		      ::= <entire variable>     |
			  <component variable>  |
			  <referenced variable>

	      Declaration of variables of type STRING:

	<identifier>{,<identifier>} : STRING {[<constant>]}

<entire variable>     ::= <variable identifier>

<variable identifier> ::= <identifier>

<component variable>  ::= <indexed variable> |
			  <field designator> |
			  <file buffer>

<indexed variable> ::= <array variable> [<expression> {,<expression>}]

<array variable>   ::= <variable>

  All Information Presented Here is Proprietary to Digital Research

				 211




<field designator> ::= <record variable> . <field identifier>

<record variable>  ::= <variable>

<field identifier> ::= <identifier>

<file buffer>	   ::= <file variable>

<file variable>	   ::= <variable>

<referenced variable> ::= <pointer variable>

<pointer variable>    ::= <variable>

<unsigned constant> ::= <unsigned number>     |
			<string>              |
			NIL                   |
			<constant identifier>

<factor>	    ::= <variable>            |
			<unsigned constant>   |
			<function designator> |
			<expression>          |
			<logical not operator> <factor>

<set>		    ::= [ <element list> ]

<e1ement 1ist>	    ::= <e1ement> {,<element>} |
			<empty>

<element>	    ::= <expression>            |
			<expression> .. <expression>

<term>		    ::= <factor> <multiplying operator> <factor>

<simple expression> ::= <term>
			<simple expression> <adding operator> <term> |
			<adding operator> <term>

<expression>	    ::= <simple expression>                       |
			<simple expression> <relational operator> |
			<simple expression>












  All Information Presented Here is Proprietary to Digital Research

				 212




<logical not operator> ::= NOT  |  ~  |  \  |  ?

	~ (synonyms \ and ?) is a NOT operator for non-booleans.

<multiplying operator> ::= *  | /  | DIV | MOD | AND | &

	& is an AND operator on non-booleans.

<adding operator>     ::= +  |  -  |  OR  |  |  |  !

	! (synonym |) is an OR operator on non-booleans.

<relational operators> ::= = | <> | < | <= | > | >= | IN

<function designator>  ::= <function identifier>                     |
			   <function identifier> ( <parm> {,<parm>})

<function identifier>  ::= <identifier>

<statement>	       ::= <label> : <unlabelled statement> |
			   <unlabelled statement>

<unlabelled statement> ::= <simple statement>       |
			   <structured statement>

<label>		       ::= <unsigned integer>

<simple statement>     ::= <assignment statement>  |
			   <procedure statement>   |
			   <goto statement>        |
			   <empty statement>

<empty statement>      ::= <empty>

<assignment statement> ::= <variable> := <expression> |
			   <function identifier> := <expression>

<procedure statement> ::= <procedure identifier>( <parm> {,<parm>}) |
			  <procedure identifier>

<procedure identifier>::= <identifier>

<parm>		      ::= <Procedure identifier>  |
			  <function identifier>   |
			  <expression>            |
			  <variable>

<goto statement> ::= goto <label>

<structured statement> ::= <repetitive statment>     |
			   <conditional statement>   |



  All Information Presented Here is Proprietary to Digital Research

				 213




			   <compound statement>      |
			   <with statement>

<compound statement> ::= BEGIN <statement> {;<statement>} END

<conditional statement> ::= <case statement> |
			    <if statement>

<if statement> ::= IF <expression> THEN <statement> ELSE <statement> |
		   IF <expression> THEN <statement>

<case statement> ::= CASE <expression> OF
			<case list> {,<case list>}
			{ELSE <statement>}
			END

<case list>	::= <label list> : <statement> |
		    <empty>

<label list>	::= <case label> {,<case label>}

<repetitive statement> ::= <repeat statement> |
			   <while statement>  |
			   <for statement>

<while statement> ::= WHILE <expression> DO <statement>

<repeat statement> ::= REPEAT <statement> {,<statement>} UNTIL
			<expression>

<for statement> ::= FOR <ctrlvar> := <for list> DO <statement>

<for list>	::= <expression> DOWNTO <expression> |
		    <expression>   TO   <expression>

<ctrlvar>	::= <variable>
<with statement>	::= WITH <record variable list> DO <statment>

<record variable list>	::= <record variable> {,<record variable>}

<procedure declaration>	::= EXTERNAL <Procedure heading> |
			    <procedure heading> <block>

<block>			::= <label declaration part>    |
			    <constant definition part>  |
			    <type definition part>      |
			    <variable declaration part> |
			    <procfunc declaration part> |
			    <statement part>

<procedure heading>	::= PROCEDURE <identifier> <parmlist>; |
			    PROCEDURE <identifier>;            |


  All Information Presented Here is Proprietary to Digital Research

				 214




			    PROCEDURE INTERRUPT [ <constant> ]

<parmlist>		::= ( <fparm> {,<fparm>} )

<fparm>			::= <procedure heading> |
			    <function heading>  |
			    VAR <parm group>    |
			    <parm group>

<parm group>		::= <identifier> {,<identifier>} :
				<type identifier>               |
			    <identifier> {,<identifier>} :
				<conformant array>

<conformant array>	::= ARRAY [ <indxtyp> {;<indxtyp>} ] OF
				<conarray2>

<conarray2>		::= <type identifier>  |
			    <conformant array>

<indxtyp>		::= <identifier> .. <identifier> : <ordtypid>

<ordtypid>		::= <scalar type identifier>     |
			    <subrange type identifier>

<label declaration part>  ::= <empty> |
			      LABEL <label> {,<label>}

<constant definition part> ::= <empty> |
			       CONST
				<constant definition>
				{;<constant definition>} ;

<type definition part>	::= <empty> |
			    TYPE
				<type definition>
				{;<type definition>} ;
<variable declaration part>	::= <empty> |
				    VAR
				    	<variable declaration>
				    	{;<variable declaration>};

<procfunc declaration part>	::= {<proc or func> ; }

<proc or func>			::= <Procedure declaration> |
				    <function declaration>

<statement part>		::= <compound statement>

<function decl>		::= EXTERNAL <function heading> |
			    <function heading> <block>



  All Information Presented Here is Proprietary to Digital Research

				 215




<function heading> ::= FUNCTION <identifier><parmlist>:<result type>; |
		       FUNCTION <identifier> : <result type> ;

<result type>	   ::= <type identifier>

<readcall>	   ::= <read or readln> {( {<filevar> ,} {<varlist>})}

<read or readln>   ::= READ | READLN

<filevar>	   ::= <variable>

<varlist>	   ::= <variable> {,<variable>}

<writecall>	   ::= <write or writeln>{({<filevar> ,} {exprlist} )}

<write or writeln> ::= WRITE | WRITELN

<exprlist>	   ::= <wexpr> {,<wexpr}

<wexpr>		   ::= <expression> {:<width expr> {:<dec expr>}}

<width expr>	   ::= <expression>

<dec expr>	   ::= <expression>

<program>	   ::= <program heading> <block> |
		       <module heading>
			 <label declaration part>
			 <constant definition part>
			 <type definition part>
			 <variable declaration part>
			 <procfunc declaration part>
			 MODEND .

<program heading>  ::= PROGRAM <identifier> {(<prog parms>)} ;

<module heading>   ::= 	MODULE <identifier> ;

<prog parms>	   ::= <identifier> {,<identifier>}















  All Information Presented Here is Proprietary to Digital Research

				 216

		    APPENDIX E: LIBRARY ROUTINES
		    ----------------------------


      The code generated  by the Pascal/MT+  compiler is true,  native
machine code. Run-time library routines are required on each processor
to support files and any other features which are not supported by the
native  hardware  but  are  required  to  implement  the entire Pascal
language. The following information is specific to the 8080/Z80,  CP/M
implementation of Pascal/MT+.

      The  Pascal/MT+  system  requires  subroutines from the run-time
library in order to support the whole of the Pascal language. All  I/O
is done  via library  routines and  SET variables  are manipulated via
library routines. Only the  run-time routines needed for  a particular
program are actually loaded when  the program is linked with  Link/MT+
when using  the IS  option. Note  that console  I/O is  assumed by the
initialize routine, @INI. This causes  the input / output routines  to
be loaded from the  run time package even  when the user is  not using
them. To avoid this, write a replacement @INI routine (similar to  the
sample in Section 1.4) and link it before linking the run time library
to resolve the reference to @INI.

      Listed below are the names of the run-time library routines  and
their function.  The purpose  of this  list is  to clarify  what these
routines  do  so  that  when  you  disassemble a program you have some
information as to what is happening in your program. They are not here
so  that  you  may  call  these  routines from your program as Digital
Research  will  not  guarantee  parameter  list  compatibility between
releases. If  you do  need to  use or  alter the  run-time library the
source is available from your distributor.

	ROUTINE	FUNCTION
	-------	-------
	@CHN	Program chaining routine

	@MUL	Integer multiply 16-bit stack

	@MUX	Integer multiply 16-bit register

	@FIN	FOR loop initialization helper

	@EQD     .
	@NED     .
	@GTD     .
	@LTD     .
	@GED	String comparison routines for
	@LED	=, <>, >, <, >=, and <=









  All Information Presented Here is Proprietary to Digital Research

				 217


	@EQS	Set equality
	@NES	Set in-equality
	@GES	Set superset
	@LES	Set subset

	@HLT	End of program halt routine, return to CP/M

	@PST	Store ret addr temporarily
	@PLD	Return ret addr to stack

	@SAD	Set union
	@SSB	Set difference
	@SML	Set intersection
	@SIN	Set membership
	@BST	Build singleton set
	@BSR	Build subrange set

	@DYN	Load/Store in stack frame mode routine
	@LNK	Allocate stack variable space
	@ULK	De-allocate stack variable space

	@EQA
	@NEA
	@GTA
	@LTA
	@GEA	Array comparison routines
	@LEA	=, <>, >, <, >= and <=

	@XJP	Table Case Jump routine

	@LBA	Load concat string buffer address
	@ISB	Init string buffer
	@CNC	Concatenate a string to the buffer
	@CCH	Concatenate a char to the buffer

	@RCH	Read a char from a file
	@CRL	Write a newline (CR) to a file
	@CWT	Wait for EOLN to be true on a file

	@INP	Handle variable port input
	@OUT	Handle variable port output

	@WIN	Write an integer to a file
	@RST	Read a string from a file

	TSTBIT	Test for a bit on
	SETBIT	Turn a bit on
	CLRBIT	Turn a bit off

	SHL	Shift a word left
	SHR	Shift a word right

	@EQI
	@NEI
	@GTI

  All Information Presented Here is Proprietary to Digital Research

				 218


	@LTI
	@GEI
	@LEI	Integer comparisons

	@EQB
	@NEB
	@GTB
	@LTB
	@GEB
	@LEB	Boolean comparisons

	@SFB	Set global FIB address
	@DWD	Set default width and decimal places
	@SIA	Reset input vector
	@SOA	Reset output vector
	@DIO	Set I/O vectors to default addresses

	@INI	Run-time initialization

	@STR	String store

	@GETCH	Read a char from a file onto stack

	@WCH	Write a string to a file

	@DIV	16-bit DIV software routine
	@MOD	16-bit MOD software routine
	@XDIVD	utility divide routine used by @WIN

	@MVL
	MOVE
	MOVELE	Block move left end to left end stack parms

	@MVR
	MOVERI	Block move right end to right end stack parms

	@PUTCH	Write a char from stack
	@LEAD	Handle width in char outputs
	@CHW	Write a char to a file
	@CHW1	entry point used by @WCH and others

	@EQR
	@NER
	@GTR
	@LTR
	@GER	Real comparisons
	@LER	=, <>, >, <, >=, and <=

	@RRL	Read a real from a file
	@WRL	Write a real to a file

	@RAD	Real add
	@RSB	Real subtract
	@RML	Real multiply
	@RDV	Real divide

  All Information Presented Here is Proprietary to Digital Research

				 219

	@RNG	Real negate

	@RAB	Real absolute value

	@XOP	Real utility load/store routine

	SQRT	Real square root

	TRUNC
	ROUND	Pascal built-in functions

	IOERR	Used for unimplement I/O routines

	CHAIN	Pascal interface for @CHN

	OPEN
	OPENX
	BLOCKR
	BLOCKW
	CREATE
	CLOSE
	CLOSED
	GNB
	WNB
	PAGE
	EOLN
	EOF
	RESET
	REWRIT
	GET
	PUT
	ASSIGN
	PURGE
	IORESU	Run time support for files

	COPY
	INSERT
	DELETE
	POS	Run time support for strings

	@WNC	Write next char to a file
	@RNC	Read next char from a file
	@RIN	Read integer from a file
	@STI	Convert string to integer
	@RNB	Read n bytes from a file
	@WNB	Write n bytes to a file

	@BDOS	Call CP/M directly

	@SPN	Check for device names
	@NOK	Check for legal file names

	@NEW	Allocate memory for NEW procedure
	@DSP	Deallocate memory for DISPOSE procedure
	MEMAVA	MEMAVAIL function
	MAXAVA	MAXAVAIL function

  All Information Presented Here is Proprietary to Digital Research

				 220




	  APPENDIX F: AMD9511 HARDWARE MATH CHIP INTERFACE
	  ------------------------------------------------

      Below are the steps required to create a hardware floating point
package which uses the 9511 AMD chip.

	1) Edit AMDIO.SRC, which is on your distribution disk, so that
	   the constant definitions for the port addresses agree with
	   your hardware configuration.

	2) Compile AMDIO.SRC.

	3) When using real numbers, instead of linking FPREALS, use
	   the construct shown below:

		LINKMT <user modules>, AMD9511/F,PASLIB/S

	   This uses the files listed in AMD9511.CMD (AMDIO, FPRTNS,
	   REALIO, and TRAN9511) rather than FPREALS. Optionally,
	   AMD9511X may be used instead of AMD9511 because it omits
	   the transcendental and real number I/O libraries.

	4) If an early release of the 9511 chip is being used,
	   declare @195 as an external procedure and call it from the
	   main program. This routine initializes the chip.

		EXTERNAL PROCEDURE @I95;



























  All Information Presented Here is Proprietary to Digital Research

				 221


























































  All Information Presented Here is Proprietary to Digital Research

				 222



	     APPENDIX G: DIRECT OPERATING SYSTEM ACCESS
	     ------------------------------------------

      For the user who wishes to use all possible CP/M function calls,
the  routine  @BDOS  from  the  run-time  package  may  be declared as
external. Passing the function  call and parameters required  to @BDOS
allows the use of all  CP/M features. The @BDOS external definition is
listed below:


	EXTERNAL FUNCTION @BDOS(FUNC:INTEGER; PARM:WORD):INTEGER;



      KEYPRESSED, a sample function which uses the @BDOS function,  is
listed below. It returns true if  a key is pressed, and returns  false
if no key is pressed.

	FUNCTION KEYPRESSED : BOOLEAN;
	BEGIN
		KEYPRESSED := (@BDOS(11,0) <> 0)
	END;

































  All Information Presented Here is Proprietary to Diqital Research

				 223


























































  All Information Presented Here is Proprietary to Diqital Research

				 224



	       APPENDIX H: INTER-PROCESSOR PORTABILIY
	       --------------------------------------

      This appendix describes those  features of Pascal/MT+ which  are
not portable to other versions of Pascal/MT+ for other microprocessors
and  operating  systems.  A  program  written  avoiding  the following
features should compile with  another Pascal/MT+ compiler with  little
or no changes to the source code.  This does not mean that all of  the
features  listed  below  are  not  implemented  on  any  other  target
processors. It  only indicates  that they  are hardware  dependent and
(if implemented) will be implemented differently in different versions
of  the  compiler.  If  any  of  these hardware dependent features are
used, isolate them so that  they are easily modified when  the program
is ported.

      Digital Research does not guarantee complete portability to  all
processors supported by the Pascal/MT+ compiler. The guidelines  which
follow  are  subject  to  change  without  notice.  There  is  no more
information concerning portability to other Pascal/MT+ compilers.

      If  the  user  wishes  to  write portable programs the following
rules should followed:

	1. Avoid pointer arithmetic. On the 8080 the pointer and
	   integer data types have been made somewhat compatible to
	   allow address arithmetic.

	2. Avoid mini-assembler and INLINE

	3. Avoid I/O ports (hardware dependent)

	4. Avoid re-directed I/O (hardware dependent)

	5. Avoid device names such as CON:, RDR:, etc.

	6. Avoid scattering calls to IORESULT througout the
	   program and isolate the calls. IORESULT values depend
	   upon the operating system.

	7. Avoid ABSOLUTE addressing (hardware dependent)

	8. Avoid INTERRUPT procedures (hardware dependent)

	9. Avoid the use of variant records which are used
	   to circumvent type checking.

       10. Avoid chaining, this is not possible to use on all
	   operating systems.

       11. Avoid having overlays call other overlays, this is
	   not possible on other operating systems.

       12. Avoid WAIT and RIM85/SIM85. (these use 8080 and 8085
           instructions)

  All Information Presented Here is Proprietary to Digital Research

				 225




       13. Avoid dependence upon EOF for non-TEXT files. It will
	   probably work differently on other operating systems.
	   This is because some operating systems keep track of
	   how much information is in the file to the exact byte
	   and some only keep track to the sector/block level and
	   the last sector/block contains "garbage" information.

       14. Avoid using "temporary" files.

       15. Avoid BLOCKREAD/BLOCKWRITE as these may not be implemented
	   on all operating systems. Use SEEKREAD/SEEKWRITE instead.

       16. Avoid the FULLHEAP logic as some operating systems provide
	   memory management which is incompatible with our garbage
	   collection.







































  All Information Presented Here is Proprietary to Digital Research

				 226





		      APPENDIX I: BIBLIOGRAPHY
		      ------------------------

'Programming in Pascal'
Peter Grogono
Addison-Wesley, Reading, Massachusetts, 1978
A good introduction for self-teaching.

'A Practical Introduction to Pascal'
I.R. Wilson and A.M. Addyman
Springer-Verlag, New York 1979
Advanced textbook

'Pascal User Manual and Report'
Kathleen Jensen and Niklaus Wirth
Springer-Verlag, New York 1974
First definition of Pascal. Best used
as a reference document.

'Draft Proposal ISO/DP 7185; Programming Languages-Pascal,
Not designed for the novice. A precise language definition.
May be obtained from American National Standards Institute,
International Sales Department, 1430 Broadway, New York, New
York, 10018. Check on price.

'PASCAL: An introduction to Methodical Programming'
William Findlay and David A. Watt
Computer Science Press, Potomac, Maryland, 1978

'A Primer on Pascal'
Richard Conway, David Gries, E. Carl Zimmerman
Winthrop Publishers, Cambridge, Massachusetts, 1976

'Pascal Programs for Scientists and Engineers'
Alan R. Miller
Sybex, Inc., Berkeley, Ca., 1981

















    All Information Presented Here is Proprietary to Digital Research

				 227


























































    All Information Presented Here is Proprietary to Digital Research

				 227



		     APPENDIX J: HEAP MANAGEMENT
		     ---------------------------

      Heap management may be done in one of two ways in the Pascal/MT+
system. The  first is  to use  the ISO  standard routines  as they are
implemented in FULLHEAP.ERL.  In this module,  the NEW routine  uses a
standard heap. Dynamic data is allocated into the smallest space which
can hold  the requested  item. The  DISPOSE actually  does dispose the
item passed to it. Garbage collection is done via the routine MAXAVAIL
(or when necessary by NEW) which gathers all of the free memory into a
free list, combines adjacent blocks, and reports the largest available
block of memory. MEMAVAIL  returns the largest never  allocated memory
space.

      The second  way in  which to  use the  heap is  to use  the NEW,
DISPOSE,  and  MEMAVAIL  which  are  part  of  the PASLIB.ERL run-time
library. In this implementation, the  heap is treated as a  stack. NEW
puts the dynamic data on top of the stack which grows from the end  of
the user's static  data towards the  hardware stack. DISPOSE  actually
does nothing. It is just there for symbol table use. The UCSD Pascal's
MARK and RELEASE  routines may be  simulated using the  system integer
SYSMEM which points to the top of the heap:

	MODULE UCSDHEAP;

	VAR
	  SYSMEM : EXTERNAL INTEGER;

	PROCEDURE MARK(VAR P:INTEGER);
	BEGIN
	  P := SYSMEM
	END;

	PROCEDURE RELEASE(P:INTEGER);
	BEGIN
	  SYSMEM := P
	END;

	MODEND.
















  All Information Presented Here is Proprietary to Digital Research

				 228


























































    All Information Presented Here is Proprietary to Digital Research

				 229



		APPENDIX K: MINI-ASSEMBLER MNEMONICS
		------------------------------------

      Listed below are the valid 8080 mini-assembler mnemonics for use
with the INLINE construct of the Pascal/MT+ compiler. Note that when
used in an INLINE construct that spaces and commas are ignored (e.g.
"MOV A,M/ is the same as "MOVAM/).

Mnemonic	Value
--------	----
NOP		000H
LXIB		001H
STAXB		002H
INXB		003H
INRB		004H
DCRB		005H
MVIB		006H
RLC		007H

DADB		009H
LDAXB		00AH
DCXB		00BH
INRC		00CH
DCRC		00DH
MVIC		00EH
RRC		00FH

LXID		011H
STAXD		012H
INXD		013H
INRD		014H
DCRD		015H
MVID		016H
RAL		017H

DADD		019H
LDAXD		01AH
DCXD		01BH
INRE		01CH
DCRE		01DH
MVIE		01EH
RAR		01FH
RIM		020H
LXIH		021H
SHLD		022H
INXH		023H
INRH		024H
DCRH		025H
MVIH		026H
DAA		027H

DADH		029H
LHLD		02AH
DCXH		02BH

  All Information Presented Here is Proprietary to Digital Research

				 231


INRL		02CH
DCRL		02DH
MVIL		02EH
CMA		02FH
SIM		030H
LXISP		031H
STA		032H
INXSP		033H
INRM		034H
DCRM		035H
MVIM		036H
STC		037H

DADSP		039H
LDA		03AH
DCXSP		03BH
INRA		03CH
DCRA		03DH
MVIA		03EH
CMC		03FH
MOVBB		040H
MOVBC		041H
MOVBD		042H
MOVBE		043H
MOVBH		044H
MOVBL		045H
MOVBM		046H
MOVBA		047H
MOVCB		048H
MOVCC		049H
MOVCD		04AH
MOVCE		04BH
MOVCH		04CH
MOVCL		04DH
MOVCM		04EH
MOVCA		04FH
MOVDB		050H
MOVDC		051H
MOVDD		052H
MOVDE		053H
MOVDH		054H
MOVDL		055H
MOVDM		056H
MOVDA		057H
MOVEB		058H
MOVEC		059H
MOVED		05AH
MOVEE		05BH
MOVEH		05CH
MOVEL		05DH
MOVEM		05EH
MOVEA		05FH
MOVHB		060H
MOVHC		061H
MOVHD		062H

  All Information Presented Here is Proprietary to Digital Research

				 232


MOVHE		063H
MOVHH		064H
MOVHL		065H
MOVHM		066H
MOVHA		067H
MOVLB		068H
MOVLC		069H
MOVLD		06AH
MOVLE		06BH
MOVLH		06CH
MOVLL		06DH
MOVLM		06EH
MOVLA		06FH
MOVMB		070H
MOVMC		071H
MOVMD		072H
MOVME		073H
MOVMH		074H
MOVML		075H
HLT		076H
MOVMA		077H
MOVAB		078H
MOVAC		079H
MOVAD		07AH
MOVAE		07BH
MOVAH		07CH
MOVAL		07DH
MOVAM		07EH
MOVAA		07FH
ADDB		080H
ADDC		081H
ADDD		082H
ADDE		083H
ADDH		084H
ADDL		085H
ADDM		086H
ADDA		087H
ADCB		088H
ADCC		089H
ADCD		08AH
ADCE		08BH
ADCH		08CH
ADCL		08DH
ADCM		08EH
ADCA		08FH
SUBB		090H
SUBC		091H
SUBD		092H
SUBE		093H
SUBH		094H
SUBL		095H
SUBM		096H
SUBA		097H
SBBB		098H
SBBC		099H

  All Information Presented Here is Proprietary to Digital Research

				 233


SBBD		09AH
SBBE		09BH
SBBH		09CH
SBBL		09DH
SBBM		09EH
SBBA		09FH
ANAB		0A0H
ANAC		0AlH
ANAD		0A2H
ANAE		0A3H
ANAH		0A4H
ANAL		0A5H
ANAM		0A6H
ANAA		0A7H
XRAB		0A8H
XRAC		0A9H
XRAD		0AAH
XRAE		0ABH
XRAH		0ACH
XRAL		0ADH
XRAM		0AEH
XRAA		0AFH
ORAB		0B0H
ORAC		0BlH
ORAD		0B2H
ORAE		0B3H
ORAH		0B4H
ORAL		0B5H
ORAM		0B6H
ORAA		0B7H
CMPB		0B8H
CMPC		0B9H
CMPD		0BAH
CMPE		0BBH
CMPH		0BCH
CMPL		0BDH
CMPM		0BEH
CMPA		0BFH
RNZ		0C0H
POPB		0C1H
JNZ		0C2H
JMP		0C3H
CNZ		0C4H
PUSHB		0C5H
ADI		0C6H
RST0		0C7H
RZ		0C8H
RET		0C9H
JZ		0CAH

CZ		0CCH
CALL		0CDH
ACI		0CEH
RST1		0CFH
RNC		0D0H

  All Information Presented Here is Proprietary to Digital Research

				 234



POPD		0DlH
JNC		0D2H
OUT		0D3H
CNC		0D4H
PUSHD		0D5H
SUI		0D6H
RST2		0D7H
RC		0D8H

JC		0DAH
IN		0DBH
CC		0DCH

SBI		0DEH
RST3		0DFH
RPO		0E0H
POPH		0ElH
JPO		0E2H
XTHL		0E3H
CPO		0E4H
PUSHH		0E5H
ANI		0E6H
RST4		0E7H
RPE		0E8H
PCHL		0E9H
JPE		0EAH
XCHG		0EBH
CPE		0ECH

XRI		0EEH
RST5		0EFH
RP		0F0H
POPPS		0FlH
JP		0F2H
DI		0F3H
CP		0F4H
PUSHP		0F5H
ORI		0F6H
RST6		0F7H
RM		0F8H
SPHL		0F9H
JM		0FAH
EI		0FBH
CM		0FCH

CPI		0FEH
RST7		0FFH








  All Information Presented Here is Proprietary to Digital Research

				 235


























































    All Information Presented Here is Proprietary to Digital Research

				 236

				INDEX
				-----

				- @ -

	@	equivalent to '^', 19, 141

	@BDOS
		source, 223
	@ERR,	119, 120
	@INI,	9, 131, 135
	@OVL,	68
	@OVS,	69
	@RNC,	9, 136
	@SFP,	130
	@WNC,	9, 136

				- A -

	ABSOLUTE variables, 107, 113
	ADDR, 83
	AMD 9511, 8, 125, 221
	AND
		and 16 bit variables, 150
	ARCTAN, 161
	ARRAY
		as procedural parameters, 159
		storage, 56
	Assembly language
		access to Pascal variables, 55
		and Pascal program interface, 54
		assemblers, 54
		functions, 58
		identifier names, 54
		parameter example, 57
		parameter passing, 57
		PUBLIC, 55
		stack, 57
	ASSIGN, 92, 173
	Assignment compatibility, 146
	Available memory message, 20

				- B -

	B switch, 19, 124
	BCD REAL, 19, 124
	BCDREALS.ERL, 7
	BDOS, 10
	Bit and byte manipulation, 80, 81, 82
	BLOCKREAD, 95, 191
	BLOCKWRITE, 95, 191
	BOOLEAN, 123
	Built-in procedures
		(see individual listings)
		ADDR, 83
		ASSIGN, 92
		BLOCKREAD, 95
		BLOCKWRITE, 95

				 237




		CLOSE, 97
		CLRBIT, 80
		CONCAT, 87
		COPY, 88
		DELETE, 90
		EXIT, 78
		FILLCHAR, 85
		GNB, 94
		HI, 82
		INSERT, 91
		IORESULT, 99
		LENGTH, 86
		LO, 82
		MAXAVAIL, 102
		MEMAVAIL, 102
		MOVE, 76
		MOVELEFT, 76
		MOVERIGHT, 76
		OPEN, 96
		POS, 89
		READHEX, 101
		RIM, 104
		SEEKREAD, 100
		SEEKWRITE, 100
		SETBIT, 80
		SHL, 81
		SHR, 81
		SIM, 104
		SIZEOF, 84
		summary of, 105
		SWAP, 82
		TSTBIT, 80
		WAIT, 103
		WNB, 94
		WRITEHEX, 101
		PURGE, 98
	BYTE, 125, 143
	Byte manipulation
		(see Bit and byte manipulation)

				- C -

	CALC.SRC, 8
	Chaining,, 107
	Chaining
		absolute variable communication, 107
		example, 107
		global variable communication, 107
		how-to, 107
		maintain heap, 107
		source file, 9
	CHAR, 123
	CHN.MAC, 9
	CHR, 123, 147, 162
	CLOSE, 97, 175

				 238




	CLOSEDEL, 97, 198
	CLRBIT, 80
	Comments
		syntax, 140
	Compiler control toggles
		entry point control $E, 21
		hardware stack pointer initialization $Z, 22
		listing controls $P/$L, 23
		real arithmetic space reduction toggle $C, 23
		recursive/static variable control $S, 21
		recursion space reduction toggle $Q, 23
		run-time range checking control $R, 22
		run-time exception checking control $X, 22
		source code include mechanism $I, 21
		strict/relaxed type checking control $T/$W, 22
		summary, 25
		symbol table control $K, 23
		syntax, 21
	Compiler
		# output, 20
		+ output, 20
		available memory, 15
		command line switch syntax, 18
		command line switches, 18
		compile time informational output, 15, 20
		execution, 18
		input files, 18
		installation, 13
		operational description, 18
		PHASE 1, 20, 26
		PHASE 2, 20, 26
		remaining memory, 15
		sample output, 15
		separate compilation, 50
		step-by-step instructions, 14
		system requirements, 5
		user table space, 15
	CON:,	92
	CONCAT, 87
	Conformant arrays, 159, 160
	Constant data at compile-time, 116
	COPY,	88
	CP/M
		devices supported, 92
	CPMRD.SRC, 9

				- D -

	Data storage, 55
	Data types
		BOOLEAN, 123
		BYTE, 125
		CHAR, 123
		INTEGER, 124
		range, 123

				 239




		REAL, 124
		SET, 129
		size, 123
		STRING, 126
		WORD, 125
	DBUGHELP.TXT, 7
	Debugger
		and compiler D switch, 41
		and recursion, 42
		command summary, 44
		command syntax, 42
		compiler switch, 19
		instructions, 41
		non-CP/M use, 41
		overview, 41
		PSY, 41
		sample link command line, 41
		SYP, 41
		undefined symbols, 42
	DEBUGGER.ERL, 7
	DELETE, 90
	DIS808O.COM, 7
	Disassembler
		example, 34
		instructions, 33
		introduction, 33
		output, 35
	DISPOSE, 229
	Distribution disk
		contents, 6
		minimum configuration, 10
	DIVMOD.MAC, 9

				- E -

	End of file, 170, 177, 179
	EOF, 113, 162, 170, 173, 175, 176, 177, 179
	EOLN, 113, 173, 175, 178
	Error handling
		run-time, 119
	Error message
		type conflict, 146
	Error messages, 199
	Exception checking
		(see Compiler control toggles)
	EXIT, 78
	Extensions to ISO standard
		(see ISO standard extensions)
	Extensions
		summary, 138
	EXTERNAL
		and assembly language modules, 55
		and entry point symbols, 21
		and modular compilation, 50
		and overlays, 62, 68

				 240




		and procedures/functions, 51
		and variables, 50
		routines as parameters, 51

				- F -

	FIB
		(see File Information Block)
	FIBDEF.LIB, 9, 169
	File Information Block, 169
	File variable, 170
	File variable Untyped files are allowed., 146
	Filename
		definition, 168
	Filenames
		associating external and internal, 92
		compiler input, 18
		linker input, 27
	Files
		sector I/O, 191
		ASCII text, 146
		ASSIGN procedure, 92
		associating files with external names, 158
		built-in procedures, 158
		chaining, 146
		closing, 97, 175
		creating, 173
		definition, 168
		deleting, 97, 98
		devices CON:, LST:, TRM:, KBD:, 92
		error handling, 99, 173
		example, 172
		fast byte routines, 94, 192
		formatted output, 164, 180
		hex input, 101
		hex output, 101
		I/O error handling, 121
		implied conversions, 146
		input/output table, 197
		interactive, 92
		local, 173, 198
		local files and linker /D switch, 28
		non-echo console input, 92
		opening (see also RESET)
		pre-defined type TEXT, 146
		primitive file access, 95
		printer output, 92
		random access, 5, 100, 184, 187
		re-directed I/O capabilities, 112
		redirected I/O capabilities, 189
		text, 169, 178, 192
		untyped, 146
		window variable, 169, 170, 174, 175, 176, 182, 187, 192
		writing to printer, 183
	FILLCHAR, 85

				 241




	Floating Point REAL, 125, 221
	Formatted output, 164, 180
	FORWARD, 159
	FPREALS.ERL, 7, 125
	FULLHEAP.ERL, 8, 102

				- G -

	GET, 176
	GNB, 94, 192
	GOTO, 154

				- H -

	Heap management
		ISO standard, 229
		MEMAVAIL and MAXAVAIL, 102
		on the stack, 229
		parameters, 162
	Hexadecimal numbers, 141
	Hexadecimal output from linker, 29
	HI, 82
	HLT.SRC, 9

				- I -
	I/O
		(see also Files)
		INP and OUT arrays description, 112
		INP and OUT examples, 112
		re-directed I/O capabilities, 112
	Identifers overlay filenames, 66
	Identifers
		and assembly language modules, 54
	Identifiers
		and @, 140, 141
		and assembly language modules, 54
		and overlays, 62
		converting to L80, 46
		external significance, 51
		legal Pascal, 141
	Include files, 21
	INLINE
		and recursion, 116
		branching, 114
		code examples, 115
		constant data example, 116
		mini-assembler, 114
		syntax, 114
	INP, 112
	INSERT, 91
	INTEGER, 124
	Interrupt procedure, 158
	Interrupt procedures
		8080/Z80, 109


				 242


		declaration, 109
		example, 109
		in ROM, 134
		Z80 mode 2, 109
	Interrupt
		hardware stack, 131
	IOERR.SRC, 10
	IORESULT, 99, 173
	ISO standard extensions
		additions to assignment compatibility rules, 153
		assembly language interfacing, 54
		BNF syntax description of Pascal/MT+, 209
		chaining, 107
		consise list of MT+ facilities, 1
		ELSE clause on CASE statement, 155
		INLINE and mini assembler, 114
		interrupt procedures, 109
		interrupt procedure example, 110
		interrupt procedures, 158
		modular compilation, 50
		operators, 150
		WRD type transfer function, 161
	ISO standard, 1
		assigment compatibility, 147
		changes from Jensen and Wirth for FOR loops, 156
		extensions for conformant arrays, 159
		summary of features, 138
		type compatibility, 147

				- K -

	KBD:, 92

				- L -

	LENGTH, 86
	LIBMT.COM, 8
	Librarian
		.BLD file, 45
		L80 conversion, 46
		linker searching, 45
		overview, 45
	Line, 178
	Linker
		/D and chaining, 107
		attributes of compatible modules, 32
		auto chain switch, 19
		command file facility switch /F, 29
		data origin switch /D, 28
		effects of /P and /D on COM file contents, 28
		effects of using /D on local files, 28
		extended map switch /E, 28
		gaining memory space, 28
		hex output switch /H, 29
		input filenames, 27
		invocation, 27
		library search switch /s, 27

				 243

		linking an overlay, 65
		linking root, 64
		load map switch /L, 28
		memory map switch /M, 28
		other linkers, 32
		overlay area switch /V, 63
		overlay example, 70
		overlay group switch /0:, 63
		overlay local storage /X:, 64
		program origin switch /P, 28
		restrictions, 58
		sample, 16
		sample output, 16
		saving space by using /D, 28
		switch summary, 30
		switches, 27
	LINKMT.COM, 7
	Listing, 19, 23
	LO, 82
	Local files
		(see Files)
	Local variable stack, 130
	LST:, 92, 183

				- M -

		MAXAVAIL, 102, 229
		MAXINT, 124
		MEMAVAIL, 102, 130, 229
		Mini-assembler, 114
		Modular compilation
			and $E toggle, 50
			and EXTERNAL, 50
			example, 51
			overview, 50
			syntax, 50
		MOVE, 76
		MOVELEFT, 76
		MOVERIGHT, 76
		MTERRS.TXT, 6
		MTPLUS.COM, 6, 10, 18

				- N -

	NEW, 229
	NOT
		and 16 bit variables, 150
	Number to string routine, 190

				- 0 -

	ODD, 123, 162
	OPEN, 96, 198
	Operators
		AND, 124
		and 16 bit variables, 150
		NOT, 124
		OR, 124

				 244



	Option Switches
		compiler, 18
		compiler example, 20
	Option switches
		linker, 27
	OR
		and 16 bit vairables, 150
	ORD, 123, 124, 147, 162
	OUTI 112
	Output
		formatted, 180
	Overlay
		@OVS, 69
		and /D switch, 65, 67
		and /P switch, 65, 67
		and root run-time routines, 70
		and run-time routines, 70
		area, 61, 62
		area numbers, 62
		area switch /V, 63, 68
		calling from root, 68
		calling on non-default drive, 69
		calling other overlays, 69
		contents of, 62
		declaration in program, 68
		entry points, 62
		error messages, 70
		EXTERNAL, 68
		features, 61
		filenames, 66
		group, 61, 62, 64, 68
		group switch	/0, 63
		linking an overlay, 65, 67
		linking example, 70
		linking root, 64, 67
		memory map, 65
		number of groups, 62
		re-linking, 66
		reload, 69
		root, 61
		root symbol file, 63, 65, 67
		sample overlay link, 73
		sample root link, 73
		space reduction, 70
		static variables, 62, 65, 67, 68, 69, 73
		static variables /X:, 64
	OVL files, 10
	OVLMGR.MAC, 10

				- P -

	PACKED, 124, 144
	PASLIB, 46
	PASLIB.ERL, 7
	PINI.SRC, 9
	Pointers, 146

				 245




	Portability,
	POS, 89
	Printer
		writing example, 183
		writing to, 183
	PRN
		(see Listing)
	Program sample
		@CMD DEMO, 79
		CHAIN1, 108
		CONCAT DEMO, 87
		CONV_DEMO (redirected I/O, strings), 190
		DEMOCON (conformant arrays), 160
		DEMO INLINE, 116
		DEMO_PROG (Overlays) , 71
		External Demo (Modular compilation), 52
		FILE_TRANSFER (Block I/O), 193
		FILE_TRANSFER (Byte I/O), 194
		FILE_TRANSFER (Random I/O), 195
		FILE_TRANSFER (GET/PUT), 196
		FILE_TRANSFER (Main Program Body), 197
		Function @BDOS (inline demo), 115
		Function KEYPRESSED, 223
		INT_DEMO (interrupt procedures), 110
		Module Overlayl, 72
		Module Overlay2, 72
		Module_Demo (modular compilation), 53
		PEEK_POKE (assembly language), 59
		PPRIME, 34
		PRINTER, 183
		Procedure @INI, 135
		Procedure @RNC, 136
		Procedure @WNC, 136
		Procedure ACCESS (strings), 127
		Procedure ADDR_DEMO, 83
		Procedure ASSIGN (strings), 126
		Procedure COMPARE (strings), 128
		Procedure COPY_DEMO, 88
		Procedure DELETE_DEMO, 90
		Procedure EXITTEST, 78
		Procedure FILL_DEMO, 85
		Procedure HI_LO_SWAP, 82
		Procedure INSERT_DEMO, 91
		Procedure LENGTH_DEMO, 86
		Procedure MOVE_DEMO, 77
		Procedure POS_DEMO, 89
		Procedure SHIFT_DEMO, 81
		Procedure SIZE_DEMO, 84
		Procedure TST_SET_CLR_BITS, 80
		Procedure WAIT_DEMO, 103
		RANDOM_DEMO, 185
		TEXTIO_DEMO, 181
		WRITE_READ_FILE_DEMO, 172
	PSY, 41
	PUN:,	92

				 246


	PURGE, 98, 198
	PUT, 174

				- R -

	Random file I/O, 5, 184
	RANDOMIO.ERL, 9
	Range checking
		(see Compiler control toggles)
		(see Run-time)
	RDR:, 92
	READ, 177
	READHEX, 101
	READLN, 182
	REAL
		B switch, 19
		BCD, 124
		floating point, 125
	RECORD
		storage, 56
	Recursion stack overflow, 26
	Recursion
		and debugger, 42
		and GOTO, 154
		compiler toggle, 21
		INLINE, 116
		INP and OUT, 112
		local files, 92, 159
		space reduction, 23
		vs. non-recursion, 117
	Redirected I/O
		and strings, 113
		ROM, 133
		sample, 189
		syntax, 112
	Remaining memory message, 20
	Requirements
		host system, 5
		run-time, 5
	Reserved words, 207
	RESET, 175
	REWRITE, 173
	RIM, 104
	ROM, 131
	ROVLMGR.ERL, 8, 69
	Run-time Library
		source, 9
	Run-time
		error handling, 119
		exception checking, 22
		range checking, 22
		ROM based considerations, 133
		routines, 217

				- S -

	Scalars

				 247



		storage, 55
	SEEKREAD, 100, 187, 192
	SEEKWRITE, 100, 187, 192
	SET, 57, 129, 145
	SETBIT, 80
	SHL, 81
	SHR, 81
	SIM, 104
	SIZEOF, 84, 191
	Space reduction
		and @INI, 133
		and linker /D switch, 28
		and overlays, 70
		and real arithmetic, 23
		and recursion, 23
		in symbol table, 23
	Stack, 57, 131
	Storage of variables, 55
	STRING, 178
	STRING implementation details, 126
	String to number routine, 190
	STRING
		access, 127
		and interrupt procedures, 109
		and READLN, 182
		and redirected I/O, 113
		assignment, 126
		below $100H, 113
		comparison, 128
		CONCAT, 87
		COPY, 88
		default length, 144
		definition, 126, 143
		explicit length declaration, 144
		null string, 142
		run-time error, 119
		use as arrays of characters, 148
	Strings
		DELETE, 90
		INSERT, 91
		LENGTH, 86
		POS, 89
	SWAP, 82
	Symbols nested comments, 140
	Symbols
		identifier significance, 141
		use of @ in identifiers, 140
		use of hexadecimal numeric literals, 141
		use of underscore in identifiers, 141
	SYP, 41
	SYSMEM, 65, 130, 229

				- T -

	TEXT files
		definition, 178

				 248




	TPA, 5
	TRANCEND.ERL, 7
	TRM:,	92
	TSTBIT, 80
	Type checking toggle, 22
	Type conflict
		error, 146
	Types
		ABSOLUTE attribute for variables, 113
		data implementation, 123
		extended, 143
		file types, 146
		implementation of PACKED, 144
		pointers, 146
		pre-defined, 143
		range of SET type, 145
		restrictions on use of ABSOLUTE with strings, 113

				- U -

	User table space, 20

				- V -

	Variable access
		assembly language variables from Pascal modules, 55
		Pascal variables from assembly language modules, 55
	Variable allocation, 55

				- W -

	WAIT, 103
	Window variable
		(see Files)
	WNB, 94, 192
	WORD, 125, 143
	WRD, 123, 147, 161, 162
	WRITE, 174
	WRITEHEX, 101
	WRITELN
		and text files, 179















				 249


