Turbo Pascal Reference Manual Feb84
Turbo Pascal Reference Manual Feb84
)) BORLAnD
. ) INTERNATIONAL
Borland International
4113 Scotts Valley Drive
Scotts Valley, California 95066
Copyright Notice ©
This software package and manual are copyrighted 1983, 1984 by BORLAND
INTERNATIONAL Inc. All rights reserved worldwide. No part of this publication
may be reproduced, transmitted, transcribed, stored in any retrieval system,
or translated into any language by any means without the express written per-
mission of BORLAND INTERNA TlONAL Inc., 4113 Scotts Valley Drive, Scotts Valley,
CA 95066, USA.
The price paid for one copy of TURBO Pascal licenses you to use the product
on one CPU when and only when you have signed and returned the License
Agreement printed in this book.
Disclaimer
TABLE OF CONTENTS I
1.8.7 Block Commands ..................................... 28
1.8.8 Miscellaneous Editing Commands ........................ 30
1.9 The TURBO editor VS. WordStar ........................... 34
1.9.1 Cursor Movement ..................................... 34
1.9.2 Mark Single Word ..................................... 34
1.9.3 End Edit ............................................ 35
1.9.4 Line Restore ......................................... 35
1.9.5 Tabulator ............................................ 35
1.9.6 Auto Indentation ...................................... 35
7. STATEMENTS ........................................ 55
7.1 Simple Statements ..................................... 55
7.1.1 Assignment Statement .................................. 55
7.1.2 Procedure Statement .................................. 56
7.1.3 Goto Statement ...................................... 56
7.1.4 Empty Statement ..................................... 56
7.2 Structured Statements .................................. 57
7.2.1 Compound Statement .................................. 57
7.2.2 Conditional Statements ................................ 57
7.2.2.1 If Statement ........................................ 57
7.2.2.2 Case Statement ..................................... 58
7.2.3 Repetitive Statements ................................. 59
7.2.3.1 For Statement ...................................... 60
7.2.3.2 While statement .................................... 61
7.2.3.3 Repeat Statement ................................... 61
TABLE OF CONTENTS v
16.2.2.11 Randomize ...................................... 129
16.2.2.12 Move .. ·........................................ 129
16.2.2.13 FiIiChar ......................................... 129
16.3 Functions ........................................... 130
16.3.1 Function Declaration ................................. 130
16.3.2 Standard Functions ................................. 132
16.3.2.1 Arithmetic Functions ............................... 132
16.3.2.1.1 Abs ........................................... 132
16.3.2.1.2 ArcTan ........................................ 132
16.3.2.1.3 Cos .................................... ; ...... 132
16.3.2.1.4 Exp ........................................... 133
16.3.2.1.5 Frac ........................................... 133
16.3.2.1.6 Int ............................................ 133
16.3.2.1.7 Ln ............................................ 133
16.3.2.1.8 Sin ........................................... 133
16.3.2.1.9 Sqr ........................................... 134
16.3.2.1.10 Sqrt .......................................... 134
16.3.2.2 Scalar Functions .................................. 134
16.3.2.2.1 Pred .......................................... 134
16.3.2.2.2 Succ .......................................... 134
16.3.2.2.3 Odd ........................................... 134
16.3.2.3 Transfer Functions .................................. 135
16.3.2.3.1 Chr ........................................... 135
16.3.2.3.2 Ord ........................................... 135
16.3.2.3.3 Round ......................................... 135
16.3.2.3.4 Trunc ......................................... 135
16.3.2.4 Miscellaneous Standard Functions .................... 136
16.3.2.4.1 Hi ............................................ 136
16.3.2.4.2 KeyPressed ..................................... 136
16.3.2.4.3 Lo ............................................ 136
16.3.2.4.4 Random ....................................... 136
16.3.2.4.5 Random(Num") .................................. 136
16.3.2.4.6 SizeOf ......................................... 137
16.3.2.4.7 Swap ......................................... 137
16.3.2.4.8 UpCase ........................................ 137
16.4 Forward References ................................... 138
TABLE OF CONTENTS IX
B.3 The CP/M-B6 Implementation ........................... 201
B.3.1 Standard Identifiers .................................. 201
B.3.2 Function Calls ....................................... 201
B.3.3 User Written I/O Drivers ............................... 201
B.3A File Interface Blocks .................................. 202
B.3.5 Random Access Files ................................. 204
TU RBO Pascal
INTRODUCTION 1
In-line machine code generation
I nclude files
Logical operations on integers
Program chaining with common variables
Random access data files
Structured constants
Type conversion functions
1: Chapter 1 describes the installation and use of TURBO Pascal, the built-in
editor, etc. This information applies to all three implementations.
2: The main body of the manual, chapters 2 through 17 , describe the com-
mon parts of TURBO Pascal, i.e. those parts of the language which are
identical in all three versions. These include Standard Pascal and many ex-
tensions. As long as you use the language as described in these chapters,
your programs will be fully portable between implementations.
3: Appendices A and B describe items which have not been covered in pre-
vious chapters because they differ among implementations, e.g. special
features, requirements, and limitations of each implementation. To avoid
confusion, you need only read the one appendix pertaining to your
implementation. These appendices mostly describe the more intricate de-
tails of programming (e.g. direct memory and port accesses, user written
I/O drivers, internal data formats, etc.), and need only be read by those
who wish to use TURBO Pascal to its fullest extent. Remember, however,
that as these things are implementation dependent, programs using them
are no longer directly portable between implementations.
4: The remaining appendices are common to all implementations and contain
summaries of language elements, syntax diagrams, error messages, an
alphabetical subject index, etc.
Common appendices
Typography
The body of this manual is printed in normal typeface. Special characters are
used for the following special purposes:
INTRODUCTION 3
Margins Certain sections, like this one, are printed in smaller type and with an
extra wide margin. This indicates that their contents is of a less impor-
tant nature than the surrounding text, and that they may therefore be
skipped on a first reading of this manual.
Syntax Descriptions
Reserved words are printed in boldface, standard identifiers use mixed upper
and lower case, and elements explained in the text are printed in italics.
The text will explain that St1, St2, and StN must be string expressions. The
syntax description shows that the word Concat must be followed by two or
more string expressions, separated by commas and enclosed in parentheses.
In other words, the following examples are legal (assuming that Name is a
string variable):
ConcatC'TORBO',' Pascal')
Concat C'TIT' , 'RID' " Pascal')
ConcatC 'T', 'U', 'R', 'B', '0' ,Name)
This chapter describes the installation and use of the TURBO Pascal system.
specifically the built-in editor.
Files with the extension .COM mark the executable program files in CP/M -80
and MS-DOS / PC-DOS. In CP/M-86 these will instead be marked .CMD.
Thus. whenever .COM -files are mentioned in the following. it should be un-
derstood as .CMD if your operating system is CP/M-86.
Before using the TURBO Pascal you should. for your own protection. make a
work-copy of the distribution diskette and store the original safely away. Re-
member that the User's License allows you to make as many copies as you
need for your own personal use and for backup purposes only. Use a file-
copy program to make the copy. and make sure that all files are successfully
transferred.
When you have a copy of the system on your work-disk, enter the command
TURBO
at your terminal. The system will log on with the following message:
In the first line, n.nn identifies your release number and [versionJ indicates the
operating environment (operating system and CPU),
e.g. CP/M- 86 on IBM PC PC. The third line tells you which screen is instal-
led. At the mo
ment none - but more about that later.
If you enter a V in response to the question, the error message file will be read
into memory (if it is on the disk), briefly displaying the
message Loading TURBO. MSG. You may instead answer N and save about
1.5 Kbytes of
memory. Then the TURBO main menu will appear:
Logged drive: A
Work file:
Main file:
Text: G bytes
Free: 62903 bytes
The menu shows you the commands available, each of which will be descri-
bed in detail in following sections. Each command is executed by entering the
associated capital letter (highlighted after terminal installation if your terminal
has that feature). Don't press <RETURN), the command executes im-
mediately. The values above for Logged drive and memory use are for the
sake of example only; the values shown will be the actual values for your
computer.
IBM PC users can use TURBO as it comes and may skip the following and go
to section 1.7 . If you're an non-IBM PC user, you may use TURBO without
installation if you don't plan to use the built-in editor - but assuming that you
do, type Q now to leave TURBO for a minute to perform the installation.
1.6 Installation
Type TINST to start the installation program. All TlNST files and the
TURBO. COM file must be on the logged drive. This menu will appear:
Enter S, C, or Q:
When you hit 5 to perform Screen installation, a menu will appear which lets
you select the sCreen mode you want to use while running TURBO (see ap-
pendix N for details). When you have made your choice, the main menu re-
appears, and you may now continue with the Command installation de-
scribed in section 1.6.3 or you may terminate the installation at this point by
entering Q for Quit.
Now hit S to select Screen installation. A menu containing the names of the
mostly used terminals will appear, and you may choose the one that suits you
by entering the appropriate number. If your terminal is not on the menu, nor
compatible with any of these (note that a lot of terminals are compatible with
e.g. ADM -3AL then you must perform the installation yourself. This is quite
straightforward, but you will need to consult the manual that came with your
terminal to answer the questions asked by the installation menu. See appen-
dix N for details.
When you have chosen a terminal, you are asked if you want to modify the in-
stallation before installation. This can be used if you have e.g. an ADM -3A
compatible terminal with some additional features. Choose the ADM -3A and
add the required commands to activate the special features. If you answer
Yes, you will be taken through a series of questions as described in appendix
N.
Normally, you will answer No to this question, which means that you are sa-
tisfied with the pre-defined terminal installation. Now you will be asked the
operating frequency of your microprocessor. Enter the appropriate value (2, 4,
6 or 8, most probably 4).
After that, the main menu re-appears, and you may now continue with the
Command installation described in the next section or you may terminate the
installation at this point by entering Q for Quit.
CURSOR MOVEMENTS:
This tells you that the command to move the cursor one character to the left
is currently a Ctrl-S (Control-S, i.e. hold down the key marked CONTROL or
CTRL and press 5), as in WordStar. If you want to use another command, you
may enter it following the - > in either of two ways:
1) Simply press the key you want to use. It could be a function key (e.g. a
left-arrow-key, if you have it) or any other key or sequence of keys that
you choose (max. 4). The installation program responds with a mnemonic
of each character it receives. If you have a left-arrow-key that transmits an
<ESCAPE> character followed by a lower case a, and you press this key in
the situation above, your screen will look like this:
CURSOR MOVEMENTS:
2) Instead of pressing the actual key you want to use, you may enter the AS-
CII value(s) of the character(s) in the command. The values of multiple
characters are entered separated by spaces. Decimal values are just ente-
red: 27; hexadecimal values are prefixed by a doliar-sign:$lB. This may be
useful to install commands which are not presently available on your key-
board, e.g. if you want to install the values of a new terminal while still us-
ing the old one. This facility has just been provided for very few and rare
instances, because there is really no idea in defining a command that can-
not be generated by pressing a key. But it's there for those who wish to
use it.
You may enter a - (minus) to remove a command from the list, and a B backs
through the list one item at a time.
The editor accepts a total of 45 commands, and they may all be changed to
your specification. If you make an error in the installation, e.g. define the same
command for two different purposes, an self-explanatory error message is is-
sued, and you must correct the error before terminating the installation. The
following table lists the default value and the use of each command, and
space is allowed for you to mark your changes, if any.
CURSOR MOVEMENTS:
BLOCK COMMANDS:
Items 2 and 28 let you define alternative commands to Character Left and
Delete left Character commands. Normally (85) is the alternative to Ctrl-5,
and there is no defined alternative to (DEL>. You may redefine these to suit
your keyboard, e.g. to use the (85) as an alternative to (DEL> if the (85)
key is more conveniently located. Of course, the two alternative commands
must be unambiguous like all other commands.
After installation, you once again activate TURBO Pascal by typing the com-
mand TURBO. Your screen should now clear and display the menu, this time
with the command letters highlighted. If not, check your installation data.
Logged drive: A
Work file:
l!ain file:
Text: 0 bytes
Free: 62903 bytes
>D
This menu shows you the commands available to you while working with
TURBO Pascal. A command is activated by pressing the associated upper
case (highlighted) letter. Don't press (RETURN), the command is executed
immediately. The menu may very well disappear from the screen when work-
ing with the system; it is easily restored by entering an 'illegal command', i.e.
any key that does not activate a command. (RETURN) or (SPACE) will do
perfectly.
The L command is used to change the currently logged drive. When entering
an L, the following prompt is issued:
New drive: •
inviting you to enter a drive name, i.e. a letter from A through P, optionally fol-
lowed by a colon and terminated with (RETURN). If you don't want to
change the current value, just hit (RETURN). The L command performs a
disk-reset, even when you don't change the drive, and should therefore be
used whenever you change disks to avoid a fatal disk write error (CP/M only!).
The new drive is not immediately shown on the menu, as it is not automati-
cally updated. Hit e.g. (SPACE) to display a fresh menu which will show the
new logged drive.
The W command is used to select a work file, i.e. the file to be used to Edit,
Compile, Run, eXecute, and Save. The W command will issue this com-
mand:
Work f i Ie name: II
and you may respond with any legal file name, i.e. a name of one through
eight characters, an optional period, and an optional file type of no more than
three characters:
FILENAME. TYP
If you enter a file name without period and file type, the file type PAS is auto-
matically assumed and appended to the name. You may explicitly specify a
file name with no file type by entering a period after the name, but omitting
the type.
Examples:
P.RCGRAM becomesPROGRAM. PAS
PROGRAM. is not changed
PROGRAM. FIL is not changed
File types .BAK, .CHN, and .COM/.CMD should be avoided, as TURBO uses
these names for special purposes.
When the Work file has been specified, the file is read from disk, if present. If
the file does not already exist, the message New Fi Ie is issued. If you have
edited another file which you have not saved, the message:
warns you that you are about to load a new file into memory and overwrite
the one you have just worked on. Answer V to save or N to skip.
The new work file name will show on the menu the next time it is updated,
e.g. when you hit (SPACE).
The M command may be used to define a main file when working with
programs which use the compiler directive $1 to include a file. The Main
file should be the file which must start the compilation, i.e. the file which
contains the include directives. You can then define the Work file to be
different from the Main file, and thus edit different include files while
leaving the name of the Main file unchanged.
When a compilation is started, and the Work file is different from the
Main file, the current Work file is automatically saved, and the Main file
is loaded into memory. If an error is found during compilation, the file
containing the error (whether it is the Main file or an include file) auto-
matically becomes the Work file which may then be edited. When the
error has been corrected and compilation is started again, the corrected
Work file is automatically saved, and the Main file is re-Ioaded.
The Main file name is specified as described for the Work file name in
the previous section.
The E command is used to invoke the built-in editor and edit the file defined
as the Work file. If no Work file is specified, you are first asked to specify one.
The menu disappears, and the editor is activated. More about the use of the
editor in section 1.8 .
While you may use the TURBO system to compile and run programs without
installing a terminal, the use of the editor requires that your terminal be instal-
led. See section 1 .6 .
The S command is used to save the current Work file on disk. The old version
of this file, if any, will be renamed to .BAK, and the new version will be saved.
The X command lets you run other programs from within TURBO Pas-
cal, e.g. copying programs, word processors - in fact anything that you
can run from your operating system. When entering X, you are promp-
ted:
Command: 0
You may now enter the name of uny program which will then load and
run normally. Upon exit from the program, control is re-transferred to
TURBO Pascal, and you return to the TURBO prompt> .
The D command gives you a directory listing and information about remaining
space on the logged drive. When hitting D, you are prompted thus:
Dir mask: 0
You may enter a drive designator or a drive designator followed by a file name
or a mask containing the usual wildcards *and? . Or you may just hit
<RETURN) to get a full directory listing.
The Quit command is used to leave the TURBO system. If the Work file has
been edited since it was loaded, you are asked whether you want to save it
before quitting.
The 0 command selects a menu on which you may view and change
some default values of the compiler. It also provides a helpful function
to find run-time errors in programs compiled into object code files.
Using the TURBO editor is simple as can be: when you have defined a Work
file and hit E, the menu disappears, and the editor is activated. If the Work file
exists on the drive, it is loaded and the first page of text is displayed. If it is a
new file, the screen is blank apart from the status line at the top.
Text is entered on the keyboard just as if you were using a typewriter. To ter-
minate a line, press the <RETURN) key (or CR or ENTER or whatever it is cal-
led on your keyboard). When you have entered enough lines to fill the screen,
the top line will scroll off the screen, but don't worry, it is not lost, and you
may page back and forth in your text with the editing commands described la-
ter.
Let us first take a look at the meaning of the status line at the top of the
screen.
Line n Shows the number of the line containing the cursor counted
from the start of the file.
Coin Shows the number of the column containing the cursor coun-
ted from the left side of the screen.
The TURBO editor accepts a total of 45 editing commands to move the cur-
sor around, page through the text, find and replace text strings, etc, etc. These
commands can be logically grouped into the following four categories:
Each of these groups contain logically related commands which will be desc-
ribed separately in following sections. The following table provides an over-
view of the commands available:
In a case like this, the best way of learning is by doing; so start TURBO, spe-
cify one of the demo Pascal programs as Work file, and enter E to Edit. Then
try the commands as you read on.
Hang on, even if you find it a bit hard in the beginning. It is not just by chance
we have chosen to make the TURBO editor WordStar compatible - the logic
of these commands, once learned, quickly become so much a part of you that
the editor virtually turns into an extension of your mind. Take it from one who
has written megabytes worth of text with that editor. Deep in the night this
man/machine synthesis reaches frightening proportions.
The (CONTROL> key works like the (SHIFT) key: if you hold down the
(SHIFT) key and press A, you will get a capital A; if you hold down the
(CONTROL> key and press A, you will get a Control-A (Ctrl-A for short).
The command which takes you out of the editor is described in section 1 .8.8 ,
but you may find it useful to know already now that the Ctrl-K Ctrl-O com-
mand exits the editor and returns you to the menu environment. This com-
mand does not automatically save the file; that must be done with the Save
command from the menu.
The most basic thing to learn about an editor is how to move the cursor
around on the screen, The TURBO editor uses a special group of control cha-
racters to do that, namely the control characters A,S, 0, F, E, R, X, and C.
Why these? Because they are conveniently located close to the control-key,
so that your left little finger can rest on that while you use the middle and in-
dex fingers to activate the commands. Furthermore, the characters are arran-
ged in such a way on the keyboard as to logically indicate their use. Let's exa-
mine the basic movements: cursor up, down, left, and right:
E
S D
X
These four characters are placed so that it is logical to assume that Ctrl-E mo-
ves the cursor up, Ctrl-X down, Ctrl-S to the left, and Ctrl-D to the right. And
that is exactly what they do. Try to move the cursor around on the screen with
these four commands. If your keyboard has repeating keys, you may just hold
down the control key and one of these four keys, and the cursor will move ra-
pidly across the screen.
E R
A 'S D F
X C
The location of the Ctrl-R next to the Ctrl-E implies that Ctrl-R moves the cur-
sor up, and so it does, only not one line at the time but a whole page. Simi-
larly, Ctrl-C moves the cursor down one page at a time.
Likewise with Ctrl-A and Ctrl-F: Ctrl-A moves to the left like Ctrl-S, but a
whole word at a time, and Ctrl-F moves one word to the right.
The two last basic movement commands do not move the cursor but scrolls
the entire screen upwards or downwards in the file:
W E R
A S D F
Z X C
Ctrl-W scrolls up in the file (the lines on the screen move down). and Ctrl-Z
scrolls down in the file (the lines on the screen move up).
Moves the cursor one character to the left non-destructively, i.e. without af-
fecting the character there. <BACKSPACE) may be installed to have the
same effect. This command does not work across line breaks, i.e. when the
cursor reaches the left edge of the screen, it stops.
Moves the cursor one character to the right non-destructively, i.e. without af-
fecting the character there. This command does not work across line breaks,
i.e. when the cursor reaches the right end of the screen, the text starts scroll-
ing horizontally until the cursor reaches the extreme right of the line, in co-
lumn 128, where it stops.
Moves the cursor to the beginning of the word to the left. A word is defined as
a sequence of characters delimited by one of the following characters: Ispacel
<) ,;.()[ ] A , *
+ _/$. This command works across line breaks.
Word right Ctrl-F
Moves the cursor to the beginning of the word to the right. See the definition
of a word above. This command works across line breaks.
Line up Ctrl-E
Moves the cursor to the line above. If the cursor is on the top line, the screen
scrolls down one line.
Moves the cursor to the line below. If the cursor is on the second-last line, the
screen scrolls up one line.
Scroll up Ctrl-W
Scrolls 'up' towards the beginning of the file, one line at a time (i.e. the entire
screen scrolls down). The cursor remains on its line until it reaches the bottom
of the screen.
Scrolls 'down' towards the end of the file, one line at a time (i.e. the entire sc-
reen scrolls up). The cursor remains on its line until it reaches the top of the
screen.
Page up Ctrl-R
Moves the cursor one page up with an overlap of one line, i.e. the cursor mo-
ves one screenful less one line backwards in the text.
Moves the cursor one page down with an overlap of one line, i.e. the cursor
moves one screenful less one line forwards in the text.
The commands discussed above will let you move freely around in your pro-
gram text, and they are easy to learn and understand. Try to use them all for a
while and see how natural they feel.
Once you master them, you will probably sometimes want to move more
rapidly. The TURBO editor provides five commands to move rapidly to the ex-
treme ends of lines, to the beginning and end of the text, and to the last cursor
position.
E R
S D
X C
i.e. Ctrl-O Ctrl-S moves the cursor to the extreme left of the line, and. Ctrl-Q
Ctrl-D moves it to the extreme right of the line. Ctrl-Q Ctrl-E moves the cursor
to the top of the screen, Ctrl-Q Ctrl-X moves it to the bottom of the screen.
Ctrl-O Ctrl-R moves the cursor all the way 'up' to the start of the file, Ctrl-Q
Ctrl-C moves it all the way 'down' to the end of the file.
Moves the cursor all the way to the left edge of the screen, i.e. to column one.
Moves the cursor to the end of the line, i.e. to the position following the last
printable character on the line. Trailing blanks are always removed from all li-
nes to preserve space.
Finally the Ctrl-Q prefix with a B, K, or P control character allows you to jump
far within the file:
Moves the cursor to the the position of the block begin marker set with Ctrl-K
Ctrl-B (hence the B). The command works even if the block is not displayed
(see hide/display block later). or the block end marker is not set.
Moves the cursor to the position of the block end marker set with Ctrl-K Ctrl-
K (hence the K). The command works even if the block is not displayed (see
hide /display block later). or the block begin marker is not set.
Moves to the last position of the cursor (the P being a mnemonic for Posi-
tion). This command is particularly useful to move back to the last position af-
ter a S ave operation or after a find or find/replace operation.
These commands let you insert and delete characters, words, and lines. They
can be divided into three groups: one command which controls the text entry
mode (insert or overwrite), a number of simple commands, and one extended
command.
Notice that the TURBO editor provides a 'regret' facility which lets you
'undo' changes as long as you have not left the line. This command (Ctrl-Q
Ctrl-L) is described in section 1.8.8 .
When you enter text, you may choose between two entry modes: Insert and
Overwrite. Insert mode is the default value when the editor is invoked. and it
lets you insert new text into an existing text. The existing text to the right of
the cursor simply moves to the right while you enter the new text.
Overwrite mode may be chosen if you wish to replace old text with new text.
Characters entered then replace existing characters under the cursor.
You switch between these modes with the insert mode on/off command Ctrl-
V, and the current mode is displayed in the status line at the top of the screen.
Moves one character to the left and deletes the character there. Any cha-
racters to the right of the cursor move one position to the left. The (BACK-
SPACE) key which normally backspaces non-destructively like Ctrl-S may be
installed to perform this function if it is more conveniently located on your
keyboard. or if your keyboard lacks a (DELETE) key (sometimes labeled
(DEL), (RUBOUT), or (RUB»). This command works across line breaks, i.e.
you can use it to remove line breaks.
Deletes the character under the cursor and moves any characters to the right
of the cursor one position to the left. This command does not work across line
breaks.
Deletes the word to the right of the cursor. A word is defined as a sequence of
characters delimited by one of the following characters: Ispacel ( ) , ; . ( ) [ ]
A •
* + - I $. This command works across line breaks, i.e. it may be used to re-
move line breaks.
Inserts a line break at the cursor position. The cursor does not move.
Deletes the line containing the cursor and moves any lines below one line up.
The cursor moves to the left edge of the screen. No provision exists to restore
a deleted line, so take care!
Deletes all text from the cursor position to the end of the line.
All block commands are extended commands (Le. two characters each in the
standard command definition)' and you may ignore them at first if you feel a
bit dazzled at this point. Later on, when you feel the need to move, delete, or
copy whole chunks of text, you should return to this section.
A block of text is simply any amount of text, from a single character to several
pages of text. A block is marked by placing a Begin block marker at the first
character and an End block marker at the last character of the desired portion
of the text. Thus marked, the block may be copied, moved, deleted, and writ-
ten to a file. A command is available to read an external file into the text as a
block, and a special command conveniently marks a single word as a block.
This command marks the beginning of a block. The marker itself is not visible
on the screen, and the block only becomes visibly marked when the End block
marker is set, and then only if the screen is installed to show some sort of
highlighting. But even if the block is not visibly marked, it is internally marked
and may be manipulated.
This command marks the end of a block. As above, the marker itself is not vi-
sible on the screen, and the block only becomes visibly marked when the Be-
gin block marker is also set.
This command marks a single word as a block, and thus replaces the Begin
block - End block sequence which is a bit clumsy when marking just one
word. If the cursor is placed within a word, then this word will be marked; if
not then the word to the left of the cursor will be marked. A word is defined as
a sequence of characters delimited by one of the following characters: Ispacel
*
<) , ;. () [ r ' + - /$.
This command causes the visual marking of a block (dim text) to be alterna-
tely switched off and on. Block manipulation commands (copy, move, delete,
and write to a file) work only when the block is displayed. Block related cursor
movements (jump to beginning/end of block) work whether the block is hid-
den or displayed.
This command places a copy of a previously marked block starting at the cur-
sor position. The original block is left unchanged, and the markers are placed
around the new copy of the block. If no block is marked, the command per-
forms no operation, and no error message is issued.
This command moves a previously marked block from its original position to
the cursor position. The block disappears from its original position and the
markers remain around the block at its new position. If no block is marked,
the command performs no operation, and no error message is issued.
This command deletes the previously marked block. No provision exists to re-
store a deleted block, so take care!
This command is used to read a file into the current text at the cursor position,
exactly as if it was a block that was moved or copied. The block read in is
marked as a block. When this command is issued, you are prompted for the
name of the file to read. The file specified may be any legal filename. If no file
type is specified, .PAS is automatically assumed: A file without type is speci-
fied as a name followed by a period.
This command is used to write a previously marked block to a file. The block
is left unchanged, and the markers remain in place. When this command is is-
sued, you are prompted for the name of the file to write to. If the file specified
already exists, a warning is issued before the existing file is overwritten. If no
block is marked, the command performs no operation, and no error message
is issued.The file specified may be any legal filename. If no file type is speci-
fied, .PAS is automatically assumed. A file without type is specified as a name
followed by a period. Avoid the use offile types .BAK, .CHN, and .COM/.CMD,
as they are used for special purposes by the TURBO system.
This section collects a number of commands which do not logically fall into
any of the above categories. They are nonetheless important, especially this
first one:
This command ends the edit and returns to the main menu. The editing has
been performed entirely in memory, and any associated disk file is not affec-
ted. Saving the edited file on disk is done explicitly with the Save command
from the main menu or automatically in connection with a compilation or
definition of a new Work file.
Tab Ctrl-I
There are no fixed tab positions in the TURBO editor. Instead, tab positions
are automatically set to the beginning of each word on the line immediately
above the cursor. This provides a very convenient automatic tabbing feature
especially useful in program editing where you often want to line up columns
of related items, e.g. variable declarations and such. Remember that Pascal
allows you to write extremely beautiful source texts -do it, not for the sake of
the purists, but more importantly to keep the program easy to understand,
especially when you return to make changes after some time.
The auto tab feature provides automatic indentation. When active, the inden-
tation of the current line is repeated on each following line, i.e. when you hit
<RETURN), the cursor does not return to column one but to the starting co-
lumn of the line you just terminated. When you want to change the indenta-
tion, use any of the cursor right or left commands to select the new column.
When auto tab is active, the message Indent is displayed in the status line,
and when passive the message is removed. Auto tab is active by default.
This command lets you regret changes made to a line as long as you have not
left the line. The line is simply restored to its original contents regardless of
what changes you have made. But only as long as you remain on the line; the
minute you leave it, changes are there to stay. For this reason, the Delete line
(Ctrl-Yl command can regrettably only be regretted, not restored. Some days
you'll find yourself continuously falling asleep on the Ctrl-Y key, with vast
consequences. A good long break usually helps.
The Find command lets you search for any string of up to 30 characters.
When you enter this command, the status line is cleared, and you are promp-
ted for a search string. Enter the string you are looking for and terminate with
<RETURN). The search string may contain any characters, also control char-
acters. Control characters are entered into the search string with the Ctrl-P
prefix: enter e.g. a Ctrl-A by holding down the Control key while pressing first
P, then A. You may thus include a line break in a search string by specifying
Ctrl-M Ctrl-J. Notice that Ctrl-A has a special meaning: it matches any cha-
racter and may be used as a wildcard in search strings.
Search strings may be edited with the Character Left, Character Right, Word
Left, and Word Right commands. Word Right recalls the previous search str-
ing which may then be edited. The search operation may be aborted with the
Abort command (Ctrl-U).
When the search string is specified, you are asked for search options. The fol-
lowing options are available:
Examples:
W search for whole words only, i.e. the search string 'term' will only
match the word 'term', not e.g. the word 'terminal'.
BU search backwards and ignore upper/lower case, i.e. 'Block' will
match both 'blockhead' and 'BLOCKADE', etc.
125 Find the 125th occurrence of the search string.
Terminate the list of options (if any) with <RETURN), and the search starts. If
the text contains a target matching the search string, the cursor is positioned
at the end of the target. The search operation may be repeated by the Repeat
last find command (Ctrl-L).
The Find and Replace command lets you search for any string of up to 30
characters and replace it with any other string of up to 30 characters. When
you enter this command, the status line is cleared, and you are prompted for a
search string. Enter the string you are looking for and terminate with <RE-
TURN). The search string may contain any characters, also control char-
acters. Control characters are entered into the search string with the Ctrl-P
prefix: enter e.g. a Ctrl-A by holding down the Control key while pressing first
P, then A. You may thus include a line break in a search string by specifying
Ctrl-M Ctrl-J. Notice that Ctrl-A has a special meaning: it matches any cha-
racter and may be used as a wildcard in search strings.
Search strings may be edited with the Character Left, Character Right, Word
Left, and Word Right commands. Word Right recalls the previous search str-
ing which may then be edited. The search operation may be aborted with the
Abort command (Ctrl-U).
When the search string is specified, you are asked to enter the string to rep-
lace the search string. Enter up to 30 caharcters; control character entry and
editing is performed as above, but Ctrl-A has no special meaning in the rep-
lace string. If you just press <RETURN>, the target will be replaced with noth-
ing, i.e. deleted.
Finally you are prompted for options. The search and replace options are:
B Search and replace backwards, i.e. search and replace from the
current cursor position towards the beginning of the text.
G Global search and replace, i.e. search and replace in the entire
text, irrespective of the current cursor position.
n n = any number. Find and replace n occurrences of the search
string, counted from the current cursor position.
N Replace without asking, i.e. do not stop and ask Replace (Y/N)
for each occruurence of the search string.
u Ignore upper/lower case, i.e. regard upper and lower case alpha-
beticals as equal.
w Search and replace whole words only, i.e. skip matching petterns
which are embedded in other words.
Examples:
N10 Find the next ten occurrences of the search string and replace
without asking.
GWU Find and replace whole words in the entire text. Ignore upper/lo-
wer case.
Terminate the list of options (if any) with <RETURN>, and the search and rep-
lace starts. Depending on the options specified, the string may be found.
When found (and if the N option is not specified), the cursor is positioned at
the end of the target, and you are asked the question: Replace (YIN)? on
the prompt line at the top of the screen. You may abort
the search and replace operation at this point with the Abort command (Ctrl-
U). The search and replace operation may be repeated by the Repeat last find
command (Ctrl-L).
This command repeats the latest Find or Find and replace operation exactly as
if all information had been re-entered.
The TURBO editor allows you to enter control characters into the file by pre-
fixing the desired control character with a Ctrl-P. If you e.g. want to enter a
Ctrl-G into a text string to ring the bell, you must first press Ctrl-P and then
Ctrl-G. Control characters are displayed as low-lighted (or inverse, or what
have you) capital letters.
The Ctrl-U command lets you abort any command in process whenever it
pauses for input, like when Search and Replace asks Replace YIN?, or during
entry of a search string or a file name (block Read and Write).
The cursor movement controls Ctrl-S, 0, E, and X move freely around on the
screen and do not jump to column one on empty lines. This does not mean
that the screen is full of blanks; on the contrary, all trailing blanks are automa-
ticaly deleted. This way of moving the cursor is especially useful e.g. when
matching indented begin - end pairs.
Ctrl-S and Ctrl-D do not work across line breaks. To move from one line to
another you must use Ctrl-E, Ctrl-X, Ctrl-A, or Ctrl-F.
Ctrl-K Ctrl-T is used to mark a single word as a block which is more conve-
nient than the two-step process of marking the beginning and the end of the
word separately.
1.9.5 Tabulator
No fixed tab settings are provided. Instead, tabs are automatically set to the
start of each word on the line immediately above the cursor.
Notes:
The basic vocabuiary of TURBO Pascal consists of basic symbols divided into
letters, digits, and special symbols:
No distinction is made between upper and lower case letters. Certain opera-
tors and delimiters are formed using two special symbols:
Assignment operator: : =
Relational operators:< > <= >=
Subrange delimiter: ..
Brackets: (. and.) may be used instead of [ and]
Comments: (* and *) may be used instead of { and}
Reserved words are integral parts of TURBO Pascal and cannot be redefined.
Reserved words must thus never be used as user defined identifiers. The re-
served words are:
Throughout this manual, reserved words are written in boldface. The aste-
risks indicate reserved words not defined in standard Pascal.
Throughout this manual, standard identifiers, like all other identifiers (see sec-
tion 4.1 ). are written in a combination of upper and lower case letters. In the
text (as opposed to program examples). they are furthermore printed in italics.
2.4 Delimiters
The maximum length of a program line is 127 characters; any character be-
yond the 127th is ignored by the compiler. For this reason the TURBO editor
allows only 127 characters on a line, but source code prepared with other edi-
tors may use longer lines. If such a text is read into the TURBO editor, line
breaks will be automatically inserted, and a warning is issued.
Notes:
A data type defines the set of values a variable may assume. Every variable in
a program must be associated with one and only one data type. Although
data types in TURBO Pascal can be quite sophisticated, they are all built from
simple {unstructured) types.
A simple type may either be defined by the programmer (it is then called a
declared scalar type). or be one of the standard scalar types: integer, real,
boolean, char, or byte. The following is a description of these five standard
scalar types.
3.1 Integer
3.2 Byte
The type Byte is a subrange of the type Integer, of the range 0 .. 255. Bytes are
therefore compatible with integers, i.e. whenever a Byte value is expected, an
Integer value may be specified instead and vice versa. Furthermore, Bytes and
Integers may be mixed in expressions and Byte variables may be assigned in-
teger values. A variable of type Byte occupies one byte in memory.
3.3 Real
Although the type real is included as a standard scalar type, the following dif-
ferences between reals and other scalar types should be noticed:
3.4 Boolean
A boolean value can assume either of the logical truth values denoted by the
standard identifiers True and False. These are defined such that False < True.
A Boolean variable occupies one byte in memory.
3.5 Char
A Char value is one character in the ASCII character set. Characters are orde-
red according to their ASCII value, e.g. 'A' < 'S'. The ordinal (ASCII) values of
characters range from 0 to 255. A Char variable occupies one byte in me-
mory.
4.1 Identifiers
Examples:
TURBO
square
personLcounted
BirthDate
3rdRoot illegal, starts with a digit
Two Words illegal, must not contain a space
As TURBO Pascal does not distinguish between upper and lower case letters,
the use of mixed upper and lower case as in BirthDate has no functional mea-
ning. It is nevertheless encouraged as it leads to more legible identifiers. Ve-
ryLongldentifier is easier to read for the human reader than VERYLONGIDEN-
TlFIER. This mixed mode will be used for all identifiers throughout this ma-
nual.
4.2 Numbers
Numbers are constants of integer type or of real type. Integer constants are
whole numbers expressed in either decimal or hexadecimal notation. Hexade-
cimal constants are identified by being preceeded by a doliar-sign:$ABC is a
hexadecimal constant. The decimal integer range is -32768 through 32767
and the hexadecimal integer range is$OOOO through$FFFF.
Examples:
1
12345
-1
$123
$ABC
$123G illegal, G is not a legal hexadecimal digit
1.2345 illegal as an integer, contains a decimal part
Examples:
1.0
1234.5678
-0.012
1E6
2E-5
-1. 2345678901E+12
1 legal, but it is not a real, it is an integer
4.3 Strings
Examples:
'TURBO'
'You' '11 see'
,., ,
The last example - the quotes enclosing no characters, denoting the empty
string - is compatible only with string types.
Examples:
u10 ASCII 10 dec imal (Line Feed).
u$lB ASCII 1B hex (Escape).
~G Control-G (Bell).
~ 1 Control-L (Form Feed). Notice that lower
case is treated as upper case.
~ [ Control-[ (Escape).
u13u10
u27~Uu20
~G~G~G~G
The above strings contain two, three, and four characters, respectively. Con-
trol characters may also be mixed with text strings:
4.4 Comments
Examples:
{ThiS is a comment}
(* and so is this *)
Curly braces may not be nested within curly braces, and C* .. *) may not be
nested within C* .. *). However, curly braces may nested withinC * .. *)
and vise versa, thus allowing entire sections of source code to be commented
away, even if they contain comments.
Examples:
program C i rc 1e s;
program Accountant (Input, Output);
program Wri ter( Input, Printer);
The declaration part of a block declares all identifiers to be used within the
statement part of that block (and possibly other blocks within it). The declara-
tion part is divided into five different sections:
Whereas standard Pascal specifies that each section may only occur zero or
one time, and only in the above order, TURBO Pascal allows each of these
sections to occur any number of times in any order in the declaration part.
Example:
label 10, error, 999, Quit;
Example:
canst
Limi t = 255;
Max = 1024;
PassWord 'SFSAM' ;
CursHome = ~ [ 'V';
The following constants are predefined in TURBO Pascal, i.e. they may be re-
ferenced without previous definition:
As described in section 13, a constant definition part may also define typed
constants.
A data type in Pascal may be either directly described in the variable de-
claration part or referenced by a type identifier. Several standard type identi-
fiers are provided, and the programmer may create his own types through the
use of the type definition. The reserved word type heads the type definition
part, and it is followed by one or more type assignments separated by semi-
colons. Each type assignment consists of a. type identifier followed by an
equal sign and a type.
Example:
type
Number = Integer;
Day = (mon,tues,wed,thur,fri,sat,sun);
List = array[ 1. .10] of Real;
Every variable occurring in a program must be declared before use. The de-
claration must textually precede any use of the variable, i.e. the variable must
be 'known' to the compiler before it can be used.
The 'scope' of this identifier is the block in which it is defined, and any block
within that block. Note, however, that any such block within another block
may define another variable using the same identifier. This variable is said to
be local to the block in which it is declared (and any blocks within that block),
and the variable declared on the outer level (the global variable) becomes
inaccessible.
Example:
var
Resul t, Intermediate, SubTotal: Real;
I, J, X, Y: Integer;
Accepted, Val id: Boolean;
Period: Day;
Buffer: arr~[0 .. 127] of Byte;
The statement part is the last part of a block. It specifies the actions to be ex-
ecuted by the program. The statement part takes the form of a compound
statement followed by a period or a semi-colon. A compound statement con-
sists of the reserved word begin, followed by a list of statements separated
by semicolons, terminated by the reserved word end.
6. EXPRESSDONS
This section describes how to form expressions from the standard scalar ty-
pes Integer, Real, Boolean, and Char. Expressions containing declared scalar
types, String types, and Set types are described in sections 8.1, 9.2 , and 12.2
, respectively.
6.1 Operators
Operators fall into five categories, denoted by their order of precedence:
If both of the operands of the mUltiplying and adding operators are of type In-
teger, then the result is of type Integer. If one (or both) of the operands is of
type Real, then the result is also of type Real.
The unary minus denotes a negation of its operand which may be of Real or
Integer types.
EXPRESSIONS 51
6.1.2 Not Operator
The not operator negates (inverses) the logical value of its Boolean operand:
TURBO Pascal also allows the not operator to be applied to an Integer ope-
rand, in which case bitwise negation takes place.
Examples:
not 0 = -1
not -15 = 14
not $2345 =$DCBA
Examples:
12 * 34 = 408
123 / 4 = 30.75
123 div 4 = 30
12 mod 5 =2
True and False = False
12 and 22 =4
2 shl 7 = 256
256 shr 7 =2
Examples:
123+456 = 579
456-123. <:) = 333.0
True or False = True
12 or 22 = 30
True xor False = True
12 xor 22 = 26
equal to
<> not equal to
> greater than
< less than
>= greater than or equal to
<= less than or equal to
Examples:
a = b true if a is equal to b.
a <> b true if a is not equal to b.
a > b true if a is greater than b.
a < b true if a is less than b.
a >= b true if a is greater than or equal to b.
a <= b true if a is less than or equal to b.
EXPRESSIONS 53
6.2 Function Designators
Examples:
Round(PlotPos)
Write In(Pi * (Sqr(R)))
(Max(X,Y) < 25) and (Z > Sqrt(X * y))
Volume(Radius,Height)
7. S1rATIEM IE ruTS
The statement part defines the action to be carried out by the program (or
subprogram) as a sequence of statements; each specifying one part of the ac-
tion. In this sense Pascal is a sequential programming language: statements
are executed sequentially in time; never simultaneously. The statement part is
enclosed by the reserved words begin and end and within it, statements are
separated by semi-colons. Statements may be either simple or structured.
Examples:
.Angle := .Angle "* Pi;
AccessOK : = False;
Ent ry : = Answer = PassWord;
SpherVol : = 4 "* Pi "* R "* R;
STATEMENTS 55
7.1.2 Procedure Statement
Examples:
Find(Name,Address);
Sort(Address) ;
Uppe rCas e ( Text) ;
UpdateCustFi le(CustRecord);
1) Before use, labels must be declared. The declaration takes place in a label
declaration in the declaration part of the block in which the label is used.
2) The scope of a label is the block in which it is declared. It is thus not pos-
sible to jump into or out of procedures and functions.
Examples:
begin end.
while Answer <> " do;
repeat until KeyPressed; {wait for any key to be hit}
Example:
if Small> Big then
begin
Tmp : = Small;
Small := Big;
Big := Tmp;
end;
7.2.2.1 If Statement
STATEMENTS 57
7.2.2.1 If Statement
if expr1 then
if expr2 then
stmt1
else
stmt2
ifexpr1 then
begin
if expr2 then
stmtT
else
stmt2
end
I.e., the else-clause part belongs generally to the last if statement which has
no else part.
Examples:
if Interest > 25 tben
Usury : = True
else
TakeLoan : = OK;
Valid selector types are all simple types, i.e. all scalar types except real.
Examples:
case Operator of
'+' : Result · - Answer + Result;
, , . Result
· - Answer - Result;
'"*' :
Result "*
· - Answer Result;
, /' : Resul t · - Answer / Result;
end;
case Year of
Min .. 1939: begin
Time . - PreWorldWar2;
Writeln('The world at peace ... ,);
end;
1946 .. Max: begin
Time . - PostWorldWar2
Wri te In( 'Bui lding a new world. ' );
end;
else
Time . = WorldWar2;
Writeln('We are at war');
end;
STATEMENTS 59
7.2.3.1 For Statement
The control variable, the initial value, and the final value must all be of the
same type. Valid types are all simple types, i.e. all scalar types except real.
If the initial value is greater than the final value when using the to clause, or if
the initial value is less than the final value when using the downto clause, the
component statement is not executed at all.
Examples:
for I . = 2 to 100 do if A[ I] > Max then Max . - A[ I] ;
for I .= 1 to NoOfLines do
begin
Readln(Line) ;
if Length(Line) < Limit then ShortLines .- ShortLines + 1
else
LongLines := LongLines + 1
end;
Notice that the component statement of a for statement must not contain as-
signments to the control variable. If the repetition is to be terminated before
the final value is reached, a goto statement must be used, although such
constructs are not recommended - it is better programming practise use a
while or a repeat statement instead.
Upon completion of a for statement, the control variable equals the final va-
lue, unless the loop was not executed at all, in which case no assignment is
made to the control variable.
The expression controlling the repetition must be of type Boolean. The sta-
tement is repeatedly executed as long as expression is True. If its value is
false at the beginning, the statement is not executed at all.
Examples:
while Size> 1 do Size .- Sqrt(Size);
while ThisMonth do
begin
ThisMonth := CurMonth SampleMonth;
Process;
{process this sample by the Process procedure}
end;
Example:
repea.t
Wri tee ~M, 'De lete thi s item? (YIN)');
Read(Answer) ;
until Up]ase(Answer) in [ 'Y' , 'N'];
STATEMENTS 61
7.2.3.3 Repeat Statement
Notes:
The basic data types of Pascal are the scalar types. Scalar types constitute a
finite and linear ordered set of values. Although the standard type Real is in-
cluded as a scalar type, it does not conform to this definition. Therefore, Reals
may not always be used in the same context as other scalar types.
Apart from the standard scalar types (Integer, Real, Boolean, Char, and Byte),
Pascal supports user defined scalar types, also called declared scalar types.
The definition of a scalar type specifies, in order, all of its possible values. The
values of the new type will be represented by identifiers, which will be the
constants of the new type.
Examples:
type
Operator (Plus,Minus,Multi,Divide);
Day (Mon,Tues,Wed,Thur,Fri,Sat,Sun);
Month (Jan, Feb, Mar ,Apr, May, Jun, Jul ,Aug, Sep, Oct ,Nov, Dec);
Card (Club,Diamond,BBart,Spade);
Variables of the above type Card can assume one of four values, namely Club,
Diamond, Heart, or Spade. You are already acquainted with the standard sca-
lar type Boolean which is defined as:
type
Boolean = (False,True);
The relational operators =, (>, >, (, >=, and (= can be applied to all
scalar types, as long as both operands are of the same type (reals and inte-
gers may be mixed). The ordering of the scalar type is used as the basis of the
comparison, i.e. the order in which the values are introduced in the type
definition. For the above type card, the following is true:
The following standard functions can be used with arguments of scalar type:
The result type of Succ and Pred is the same as the argument type. The re-
sult type of Ord is Integer.
Examples:
type
HemiSphere (North, South, East, West);
World (East, West)
Compas sRange 0 .. 360;
Upper 'A' .. 'Z';
Lower 'a' .. 'z';
Degree (Ce Ie, Fahr, Ream, Ke Iv);
Wine (Red, Whi te, Rose, Sparkling);
The type World is a subrange of the scalar type HemiSphere (called the asso-
ciated scalar type). The associated scalar type of CompasRange is Integer,
and the associated scalar type of Upper and Lower is Char.
You already know the standard subrange type Byte, which is defined as:
type
Byte", 0 .. 255;
A subrange type retains all the properties of its associated scalar type, being
restricted only in its range of values.
The use of defined scalar types and subrange types is strongly recommended
as it greatly improves the readability of programs. Furthermore, run time
checks are included in the program code (see section 8.4) to verify the values
assigned to defined scalar variables and subrange variables. Another advan-
tage of defined types and subrange types is that they often save memory.
TU RBO Pascal allocates only one byte of memory for variables of a defined
scalar type or a subrange type with a total number of elements less than 256.
Similary, integer subrange variables, where lower and upper bounds are both
within the range 0 through 255, occupy only one byte of memory.
The Ord function may be used to convert scalar types into values of type inte-
ger. Standard Pascal does not provide a way to reverse this process, i.e. a way
of converting an integer into a scalar value.
Integer(Heart) 2
Month(l0) Nov
HemiSphere( 2) East
Upper( 14) '0'
Degree( 3) Kelv
Char( 78) 'N'
Integer( '7' ) 55
The generation of code to perform run-time range checks on scalar and sub-
range variables is controlled with the R compiler directive. The default setting
is {$R -}, i.e. no checking is performed. When an assignment is made to a sca-
lar or a subrange variable while this directive is active ({ $R+}), assignment
values are checked to be within range. It is recommended to use this setting
as long as a program is not fully debugged.
Example:
program Rangecheck;
type
Digit = 0 .. 9;
Var
Dig1,Dig2,Dig3: digit;
begin
Dig1 · - 5; {valid}
Dig2 · - Dig1 + 3; {valid as Dig1 + 3 <= 9}
Dig3 · - 47; {invalid but causes no error}
{$R+} Dig3 . - 55; {invalid and causes a run time errod
{$R- } Dig3 . - 167; {invalid but causes no errod
end.
9. STRING TYPE
TURBO Pascal offers the convenience of string types for processing of cha-
racter strings, i.e. sequences of characters. String types are structured types,
and are in many ways similar to array types (see section 10). There is, howe-
ver, one major difference between these: the number of characters in a string
(i.e. the length of the string) may vary dynamically between 0 and a specified
upper limit, whereas the number of elements in an array is fixed.
The definition of a string type must specify the maximum number of charac-
ters it can contain, i.e. the maximum length of strings of that type. The defini-
tion consists of the reserved word string followed by the maximum length
enclosed in square brackets. The length is specified by an integer constant in
the range 1 through 255. Notice that strings do not have a default length; the
length must always be specified.
Example:
type
Fi leName strin.g[ 14] ;
Sc reenLine = strin.g[ 80] ;
String variables occupy the defined maximum length in memory plus one byte
which contains the current length of the variable. The individual characters
within a string are indexed from 1 through the length of the string.
The plus-sign may be used to concatenate strings. The Concat function (see
section 9.5) performs the same function, but the + operator is often more
convenient. If the length of the result is greater than 255, a run-time error oc-
curs.
STRING TYPE 67
9.2 String Expressions
Example:
'TURBO ' + 'Pascal' = 'TURBO Pascal'
, 123' + '.' + '456' = '123.456'
'A ' + 'B' + ' C ' + 'D ='A BCD'
The relational ope--rators =, (>, >, (, >=, and (= are lower in precedence
than the concatenation operator. When applied to string operands, the re--
suit is a Boolean value ( True or False). When comparing two strings, single
cha--racters are compared from the left to the right. If the strings are of
dif--ferent length, but equal up to and including the last character of the
shortest string, then the shortest string is considered the smaller.
Strings are equal only if their lengths as well as their contents are iden--
ti--cal.
Examples:
'A' < 'B' is true
'A' > 'b' is false
'2' < '12' is false
'TURBO' = 'TURBO ' is true
'TURBO ' = 'TURBO ' is false
'Pascal Compiler' < 'Pascal compiler' is true
Example:
.Age := 'fiftieth';
Line := 'Many happy returns on your' + .Age + ' birthday. ';
9.4.1 Delete
Syntax: Delete ( St , Pos ,Num )
9.4.2 Insert
Syntax: Insert ( Obj, Target, Pos )
Insert inserts the string Obj into the string Target at the position Pos.
Obj is a string expression, Target is a string variable, and Pos is an in--
teger ex--pression. If Pos is greater than Length( Target). then obj is
conca--tenated to Target. If the result is longer than the maximum length of
Target. then excess characters will be truncated and Target will only
contain the left--most characters. If Pos is out--side the range 1.. 255, a run
time error occurs.
STRING TYPE 69
9.4.3 Str
9.4.3 Str
The Str procedure con--verts the numeric value of Value into a string and
stores the result in St. Value is a write parameter of type integer or of
type real, and Str- Var is a string variable. Write parameters are ex--pres--
sions with special formatting commands (see sec--tion 14.6.3 ).
8-bit systems only: a function using the Str procedure must never be called
by an expression in a Write or Writeln statement.
9.4.4 Val
8-bit systems only: a function using the Var procedure must never be called
by an expression in a Write or Writeln statement.
9.5.1 Copy
Syntax: Copy (St , Pos , Num )
9.5.2 Concat
Syntax: Concat (St1 , St2 { , StN } )
If St1 has the value' TURBO' and St2 the value 'is fastest' then:
Concat(Stl,' PASCAL',St2)
STRING TYPE 71
9.5.3 Length
9.5.3 Length
Syntax: Length ( St )
Returns the length of the string expression St, i.e. the number of cha--rac--
ters in St. The type of the result is integer.
9.5.4 Pos
The Pas function scans the string Target to find the first occurrence of
Obj within Target. Obj and Target are string expressions, and the type of
the result is inte--ger. The result is an integer denoting the position
within Target of the first character of the matched pat--tern. The position
of the first character in a string is 1. If the pattern is not found, Pas
returns O.
String types and the standard scalar type Char are compatible. Thus, when-
ever a string value is expected, a char value may be specified instead and vice
versa. Furthermore, strings and characters may be mixed in expressions.
When a character is assigned a string value, the length of the string must be
exactly one; otherwise a run-time error occurs.
Examples:
Buffer[ 5]
Line[Length(Line)-l]
Ord(Line[0] )
As the first character of the string (at index 0) contains the length of the
string, Length(String) is the same as Ord(String[0]). If assignment is
made to the length indicator, it is the responsibility of the programmer to
check that it is less than the maximum length of the string variable. When the
range check compiler directive R is active ({ $R+}), code is generated which
insures that the value of a string index expression does not exceed the
maximum length of the string variable. It is, however, still possible to index a
string beyond its current dynamic length. The characters thus read are
random, and assignments beyond the current length will not affect the actual
value of the string variable.
STRING TYPE 73
9.6 Strings and Characters
Notes:
10. ARRAVTYPE
The definition of an array consists of the the reserved word array followed by
the index type, enclosed in square brackets, followed by the reserved word of,
followed by the component type.
Examples:
type
Day = (Mon,Tue,Wed,Thu,Fri,Sat,Sun)
Var
WorkHour arr~[1 .. 8] of Integer;
Week arr~[1 .. 7] of Day;
type
Players (Player1,Player2,Player3,Player4);
Hand (One,Two,Pair,TwoPair,Three,Straight,
Flush, FullHouse, Four, StraightFlush,RSF);
LegalBid 1. .200;
Bid arr~[Players] of LegalBid;
Var
Player ar~[Players] of Hand;
Pot Bid;
Player[Player3] : = FullHouse;
Pot [Player3] := 100;
Player[Player4] : = Flush;
Pot [Player4] := 50;
ARRAY TYPE 75
10.1 Array Definition
The R compiler directive controls the generation of code which will perform
range checks on array index expressions at run-time. The default mode is pas-
sive, i.e. {$R-l. and the { $R+} setting causes all index expressions to be
checked against the limits of their index type.
The component type of an array may be any data type, i.e. the component
type may be another array. Such a structure is called a multidimensional ar-
ray.
Example:
type
Card (Two,Three,Four,Five, Six, Seven, Eight ,Nine,
Ten,Knight,Queen,King,Ace);
Suit (Hearts,Spade,Clubs,Diamonds);
AIlCards array[Suit] of array[1 .. 13] of Card;
Var
Deck: AIlCards;
type
AIICards = array[Suit,1 .. 13] of Card;
Example:
type
Pupils string[ 10] ;
Class arr~[l .. 30] of Pupils;
Scool arr~[l .. 100] of Class;
Var
J,P,Vacant Integer
ClassA,
ClassB Class;
NewTownScool: Scool;
ClassA[J] :='Peter';
NewTownScool[5] [211: '=Peter Brown';
NewTownScoo I [8, J] : =NewTownScoo I [7, J]; {pupil no. J changed class}
C lassA[Vacant] : =ClassB[ p] ; {pupil no. P changes Class and numbed
Character arrays are arrays with one index and components of the standard
scalar type Char. Character arrays may be thought of as strings with a con-
stant length.
TURBO Pascal offers two predefined arrays of type Byte, called Mem and
Port, which are used to access CPU memory and data ports. These are
discussed in appendices A and B .
ARRAY TYPE 77
10.4 Predefined Arrays
Notes:
The definition of a record type consists of the reserved word record suc-
ceeded by a field list and terminated by the reserved word end. The field list is
a sequence of record sections separated by semi-colons, each consisting of
one or more identifiers separated by commas and terminated by a colon and a
type identifier. Each record section thus specifies the type and identifier for
one or more fields.
Example:
type
Date record
Day: 1. .31;
Month: (Jan,Feb,Mar,Apr,MaY,Jun,
July ,Aug, Sep, Oc t ,Nov, Dec);
Year: 1900 .. 1999;
end;
Var
Bi rth: Date;
WorkDay: array[ 1. .5] of date;
Day, Month, and Yearare field identifiers. A fieid identifier must be unique
only within the record in which it is defined. A field is referenced by the va-
riable identifier and the field identifier separated by a period.
Examples:
Birth.Month .- Jun;
Birth.Year := 1950;
WorkDay[Current] := workDay[Current-1];
Note that, similar to array types, assignment is allowed between entire re-
cords of identical types. As record components may be of any type, con-
structs like the following record of records of records are possible:
RECORD TYPE 79
11.1 Record Definition
type
Name record
Fami lyName: string[ 32];
ChristianNames: arr~[1 .. 3] of string[16];
end;
Rate record
NormalRate, OverI'ime,
NightTime, Weekend: Integer
end;
Date record
Day: 1. .31;
Month: (Jan,Feb,Mar,Apr,May,Jun,
JulY,Aug,Sep,Oct,Nov,Dec);
Year: 1900 .. 1999;
end;
Person = record
ID: Name;
Time: Date;
end;
Wages record
Individual: Person;
Cost: Rate;
end
Salary : = Fee;
Salary.Cost.Overtime .- 950;
Salary. Individual. Time : = Fee. Individual. Time;
Salary.Individual.ID.FamilyName := 'Smith'
11 .2 With Statement
The use of records as describes above does sometimes result in rather lengthy
statements; it would often be easier if we could access individual fields in a
record as if they were simple variables. This is the function of the with state-
ment: it 'opens up' a record so that field identifiers may be used as variable
identifiers.
A with statement consists of the reserved word with followed by a list of re-
cord variables separated by commas followed by the reserved word do and fi-
nallya statement.
Within a with statement, a field is designated only by its field identifier, i.e.
without the record variable identifier:
wi th Salary do
begin
Individual : = NewEmployee;
Cost := StandardRates;
end;
Records may be nested within with statements, i.e. records of records may
be 'opened' as shown here:
The maximum 'depth' of this nesting of with sentences, i.e. the maximum
number of records which may be 'opened' within one block, depends on your
implementation and is discussed in appendices A and B .
RECORD TYPE 81
11.3 Variant Records
The syntax of a record type also provides for a variant part, i.e. alternative re-
cord structures which allows fields of a record to consist of a different number
and different types of components, usually depending on the value of a tag
field.
and of the types Name and Date, the following record allows the field Citi-
zenShip to have different structures depending on whether the value of the
field is Citizen or Alien:
type
Person = record
PersonName: Name;
Bi rtbDate: Date;
case CitizenShip: Origin of
Citizen: (BirthPlace: Name);
Al ien: (CountryOfOrigin: Name;
DateOfEntry: Date;
Permi ttedUnt i I: Date;
PortOfEntry: Name)
end
In this variant record definition, the tag-field is an explicit field which may be
selected and updated like any other field. Thus, if Passenger is a variable of
type Person, statements like the following are perfectly legal:
Passenger.CitizenShip := Citizen;
wlthPassenger, PersonName do
if CitizenShip = Alien then writeln(FamiIYName);
The fixed part of a record, i.e. the part containing the common fields, must al-
ways precede the variant part. I n the above example, the fields PersonName
and BirthDate are the fixed fields. A record can only have one variant part. In a
variant, the parentheses must be present, even if they will enclose nothing.
RECORD TYPE 83
11.3 Variant Records
Notes:
12. SETTVPE
a
1) All integers between and 100
2) The letters of the alphabet
3) The consonants of the alphabet
Two sets are equal if and only if their elements are the same. There is no or-
dering involved, so the sets [1,3,51, [5,3,1] and [3,5,1] are all equal. If the
members of one set are also members of another set, then the first set is said
to be included in the second. In the examples above, 3) is included in 2).
There are three operations involving sets, similar to the operations addition,
multiplication and subtraction operations on numbers:
The union (or sum) of two sets A and B (written A+B) is the set whose
members are members of either A or B. For instance, the union of [1 ,3,5,7]
and [2,3,4] is [1,2,3,4,5,7].
The intersection (or product) of two sets A and B (written A*B) is the set
whose members are the members of both A and B. Thus, the intersection
of [1,3,4,5,7] and [2,3,4] is [3,4].
RECORD TYPE 85
12.1 Set Type Definition
Examples:
type
DaysOfMonth = set of 0 .. 31;
WorkWeek = set of Mon .. Fri;
Letter = set of 'A' .. 'Z';
AdditiveColors = set of (Red,Green,Blue);
Characters = set of Char;
In TURBO Pascal, the maximum number of elements in a set is 256, and the
ordinal values of the base type must be within the range 0 through 255.
Set values may be computed from other set values through set expressions.
Set expressions consist of set constants, set variables, set constructors, and
set operators.
Examples:
['T', 'U', 'R', 'B', '0']
[X,Y]
[X .. y]
[1. .5]
[ 'A' .. 'Z' , 'a' .. 'z' , '0' .. '9' ]
[1,3 .. 10,12]
[]
The last example shows the empty set, which, as it contains no expressions to
indicate its base type, is compatible with all set types. The set [1 .. 5) is equiva-
lent to the set [1,2,3,4,5]. IfX>Y then [X ..Y) denotes the empty set.
1) * Set intersection.
2) + Set union.
Set difference.
3) Test on equality.
<> Test on inequality.
>= True if the second operand is included in the first operand.
<= True if the first operand is included in the second operand.
IN Test on set membership. The second operand is of a set type, and
the first operand is an expression of the same type as the base
type of the set. The result is true if the first operand is a member
of the second operand, otherwise it is false.
A*B=[].
Set expressions are often useful to clarify complicated tests. For instance, the
test:
if (Ch= 'T') or (Cll: 'U') or (Ch= 'R') or (Ch= 'B') or (Ch= '0' )
i f (Ch >= ' 8') and (Ch < = ' 9') then
RECORD TYPE 87
12.3 Set Assignments
Values resulting from set expressions are assigned to set variables using the
assignment operator . - .
Examples:
type
ABCII = set of 0 .. 127;
Var
NoPrint, Print ,AIlChars: ASCII;
begin
AIIChars : = [0 .. 127];
NoPrint : = [0 .. 31,127];
Print : = AllChars - NoPrint;
end.
The use of a typed constant saves code if the constant is used often in a pro-
gram, because a typed constant is included in the program code only once,
whereas an untyped constant is included every time it is used.
Typed constants are defined like untyped constants (see section 5.2.2). ex-
cept that the definition speficies not only the value of the constant but also
the type. In the definition the typed constant identifier is succeeded by a colon
and a type identifier, which is then followed by an equal sign and the actual
constant.
const
NumberOfCars: Integer = 1267;
Interest: Real = 12.67;
Heading: string[7] = 'SECTION';
Xon: Char = ~Q;
const
Min: Integer 0;
Max: Integer 50;
type
Range: array[Min .. Max] of integer
TYPED CONSTANTS 89
13.2 Structured Typed Constants
Examples:
type
Status (Act ive, Pass i ve, Wai t ing);
StringRep ar~[Status] of string[7];
const
Stat: StringRep = ('active', 'paSSive', 'waiting');
The example defines the array constants Stat, which may be used to convert
values of the scalar type Status into their corresponding string represen-
tations. The components of Stat are:
The component type of an array constant may be any type except File types
and Pointer types. Character array constants may be specified both as single
characters and as strings. Thus, the definition:
const
Digits: arr~[0 .. 9] of Char =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
const
Digits: arr~[0 .. 9] of Char '0123456789';
Example:
type
Cube = arr~[0 .. 1,O .. 1,O .. 1] of integer;
const
Maze: Cube = (((O,1),(2,3»,((4,5),(6,7));
begin
Writeln(Maze[0,0,0], , 0');
Writeln(Maze[0,0,11, , 1');
Writeln(Maze[0, 1,0], , 2');
Writeln(Maze[0, 1, 11, , 3');
Writeln(Maze[I,0,0],' 4');
Writeln(Maze[l,0,11,' 5');
Writeln(Maze[I,I,0],' 6');
Writeln(Maze[ 1, 1, 11, , 7');
end.
Examples:
type
Point record
X,Y, Z: integer;
end;
as (CPM80,CPM86,MSDOS,Unix);
UI (CCP,SomethingElse,MenuMaster);
Computer record
OperatingSystems: ar~[I .. 4] of OS;
Userlnterface: UI;
end;
TYPED CONSTANTS 91
13.2.3 Record Constants
canst
Origo: Point = (X:0; Y:0; Z:0);
SuperComp: Computer =
(OperatingSystems: (CPM80,CPM86,MSDOS,Unix);
Userlnterface: MenuMaster);
Plane1: arr~[1 .. 3] of Point =
((X: 1;Y:4; Z:5), (X: 10;Y: -78; Z:45), (X: 100;Y: 10; Z: -7»;
The field constants must be specified in the same order as they appear in the
definition of the record type. If a record contains fields of file types or pointer
types, then constants of that record type cannot be specified. If a record con-
stant contains a variant, then it is the responsibility of the programmer to spe-
cify only the fields of the valid variant. If the variant contains a tag field, then
its value must be specified.
Example:
type
Up set of 'A' .. 'Z';
Low set of 'a' .. 'z';
const
UpperCase: Up ['A' .. 'Z'];
Vocals Low ['a', 'e', ' i ' , '0', 'u', 'Y'];
Delimiter: set of Char =
[, , .. , / " , : , .. ,?",[, .. ,~",{, .. ,-,];
A file type is defined by the reserved words file of followed by the type of the
components of the file, and a file identifier is declared by the same words fol-
lowed by the identifier of a previously defined file type.
Examples:
type
ProductName = string[80];
Product = file of recoDd
Name: ProductName;
IterrNumber: Real;
InStock: Real;
MinStock: Real;
Suppl ier: Integer;
end;
Var
ProductFile: Product;
ProductNames: file of ProductName;
The component type of a file may be any type, except a file type. (Le., with re-
ference to the example above, file of Product is not allowed). File variables
may appear neither in assignments nor in expressions.
FILE TYPES 93
14.2 Operations on Files
The following sections describe the procedures available for file handling. The
identifier Filvar used throughout denotes a file variable identifier declared as
described above.
14.2.1 Assign
Str is a string expression yielding any legal file name. This file name is assig-
ned to the file variable FilVar, and all further operation on FiIVar will operate
on the disk file Str. Assign should never be used on a file which is in use.
14.2.2 Rewrite
Syntax: Rewrite( FilVar)
A new disk file of the name assigned to the file variable FilVar is created and
prepared for processing. and the file pointer is set to the beginning of the file.
i.e. component no. O. Any previously existing file with the same name is era-
sed. A disk file created by rewrite is initially empty, i.e. it contains no ele-
ments.
14.2.3 Reset
Syntax: Reset( FiIVar)
The disk file of the name assigned to the file variable FilVar is prepared for
processing, and the file pointer is set to the beginning of the file, i.e. compo-
nent no. O. FilVar must name an existing file, otherwise an I/O error occurs.
14.2.4 Read
Var denotes one or more variables of the component type of FilVar, sepa-
rated by commas. Each variable is read from the disk file, and following each
read operation, the file pointer is advanced to the next component.
14.2.5 Write
Var denotes one or more variables of the component type of FilVar, sepa-
rated by commas. Each variable is written to the disk file, and following each
write operation, the file pointer is advanced to the next component.
14.2.6 Seek
Seek moves the file pointer is moved to the n'th component of the file deno-
ted by FilVar. n is an integer expression. The position of the first component is
O. Note that in order to expand a file it is possible to seek one component
beyond the last component. The statement
thus places the file pointer at the end of the file ( FileSize returns the number
of components in the file, and as the components are numbered from zero,
the returned number is one greater than the number of the last component).
14.2.7 Flush
Flush empties the internal sector buffer of the disk file FiIVar, and thus assu-
res that the sector buffer is written to the disk if any write operations have ta-
ken place since the last disk update. Flush also insures that the next read ope-
ration will actually perform a physical read from the disk file. Flush should ne-
ver be used on a closed file.
FILE TYPES 95
14.2.8 Close
14.2.8 Close
The disk file associated with FilVar is closed, and the disk directory is updated
to reflect the new status of the file. Notice that in multi-user environments it
is often necessary to Close a file, even if it has only been read from.
14.2.9 Erase
The disk file associated with FilVar is erased. If the file is open, i.e. if the file
has been reset or rewritten but not closed, it is good programming practice to
close the file before erasing it.
14.2.10 Rename
The disk file associated with FilVar is renamed to a new name given by the
string expression Str. The disk directory is updated to show the new name of
the file, and further operations on FilVar will operate on the file with the new
name. Rename should never be used on an open file.
Notice that it is the programmer's responsibility to assure that the file named
by Str does not already exist. If it does, multiple occurrences of the same
name may result. The following function returns True if the file name passed
as a parameter exists, otherwise it returns False:
function Exist(FileName: Name): boolean;
Var
Fi 1: file;
begin
Assign(Fil, FileName);
{$1 - }
Reset(Fil);
{$1+ }
Exist := OOresult 0)
end;
14.3.1 EOF
A Boolean function which returns True if the file pointer is positioned at the
end of the disk file, i.e. beyond the last component of the file. If not, EOF re-
turns False.
14.3.2 RlePos
Syntax: FilePos( FilVar)
An integer function which returns the current position of the file pointer. The
first component of a file is O.
14.3.3 RleSize
Syntax: FileSize( FilVar)
An integer function which returns the size of the disk file expressed as the
number of components in the file. If FileSize(FiIVar) is zero, the file is empty.
Before using a file, the Assign procedure must be called to assign the file
name to a file variable. Before input and/or output operations are performed.
the file must be opened with a call to Rewrite or Reset. This call will set the
file pointer to point to the first component of the disk file. i.e. FilePos(FiIVar)
= O. After Rewrite, FileSize(FiIVar) is O.
FILE TYPES 97
14.4 Using Files
A disk file can be expanded only by adding components to the end of the
existing file. The file pointer can be moved to the end of the file by executing
the following sentence:
Seek(FilVar, FileSize(FilVar»;
The program below creates a disk file called PRODUCTS.DTA, and writes 100
records of the type Product to the file. This initializes the file for subsequent
random access (i.e. records may be read and written anywhere in the file).
The following program demonstrates the use of Sseek on random files. The
program is used to update the Pro duct File created by the program in the pre-
vious example.
FILE TYPES 99
14.5 Text Files
Unlike all other file types, text files are not simply sequences of values of
some type. Although the basic components of a text file are characters, they
are structured into lines, each line being terminated by an end-of-line marker
(a CR/LF sequence). The file is further ended by an end-of-file marker (a Ctrl-
Z). As the length of lines may vary, the position of a given line in a file cannot
be calculated. Text files can therefore only be processed sequentially. Further-
more, input and output cannot be performed simultaneously to a text file.
A text file variable is declared by referring to the standard type identifier Text.
Subsequent file operations must be preceded by a call to Assign and a call to
Reset or Rewrite must furthermore precede input or output operations.
Rewrite is used to create a new text file, and the only operation then allowed
on the file is the appending of new components to the end of the file. Reset is
used to open an existing file for reading, and the only operation allowed on
the file is sequential reading. When a new textfile is closed, an end-of-file
mark is automatically appended to the file.
Character input and output on text files is made with the standard proce-
dures Read and Write. Lines are processed with the special text file operators
Rea dIn , Writeln, and Eoln :
Readln( Filvar) Skips to the beginning of the next line, i.e. skips all charac-
ters up to and including the next CR/LF sequence.
Writeln( Filvar) Writes a line marker, i.e. a CR/LF sequence, to the text-
file.
Eoln( Filvar) A Boolean function which returns True if the end of the
current line has been reached, i.e. if the file pointer is posi-
tioned at the CR character of the CR/LF line marker. If
EOF( Filvar) is true, Eoln( Filvar) is also true.
When applied to a text file, the EOF function returns the value True if the file
pointer is positioned at the end-of-file mark (the CTRl/Z character ending the
file). The Seek and Flush procedures and the FilePos and FileSize functions
are not applicable to text files.
The following sample program reads a text file from disk and prints it on the
pre-defined device Lst which is the printer. Words surrounded by Ctrl-S in the
file are printed underlined:
Further extensions of the procedures Read and Write, which facilitate conve-
nient handling of formatted input and output, are described in section 14.6 .
CON: The console device. Output is sent to the operating system's con-
sole output device, usually the CRT, and input is obtained from the
console input device, usually the keyboard. Contrary to the TRM:
device (see below), the CON: device provides buffered input. In
short, this means that each Read or Readln from a textfile assigned
to the CON: device will input an entire line into a line buffer, and
that the operator is provided with a set of editing facilities during
line input. For more details on console input. please refer to sections
14.5.3 and 14.6.1 .
TRM: The terminal device. Output is sent to the operating system's con-
sole output device, usually the CRT, and input is obtained from the
console input device, usually the keyboard. Input characters are ec-
hoed, unless they are control characters. The only control character
echoed is a carriage return (CR), which is echoed as CR/LF.
KBD: The keyboard device (input only). Input is obtained from the operat-
ing system's console input device, usually the keyboard. Input is not
echoed.
L5T: The list device (output only). Output is sent to the operating sy-
stem's list device, typically the line priner.
AUX: The auxiliary device. Output is sent to the operating system's punch
device, and input is obtained from the operating system's reader de-
vice. Usually, the punch and reader devices refer to a modem.
U5R: The user device. Output is sent to the user output routine, and input
is obtained from the user input routine. For further details on user
input and output, please refer to sections A.13 and B.3.3 .
These logical devices may be accessed through the pre-assigned files dis-
cussed in section 14.5.3 or they may be assigned to file variables, exactly like
a disk file. There is no difference between Rewrite and Reset on a file assig-
ned to a logical device, Close performs no function, and an attempt to Erase
such a file will cause an I/O error.
The standard functions Eof and Eoln operate differently on logical devices
than on disk files. On a disk file, Eof returns True when the next character in
the file is a Ctrl-Z, or when physical EOF is encountered, and Eoln returns True
when the next character is a CR or a Ctrl-Z. Thus, Eof and Eoln are in fact
"Iook ahead" routines.
As you cannot look ahead on a logical device, Eoln and Eof operate on the last
character read instead of on the next character. In effect, Eof returns True
when the last character read was a Ctrl-Z, and Eoln returns True when the last
character read was a CR or a Ctrl-Z. The following table provides an overview
of the operation of Eoln and Eof:
Input The primary input file. This file is assigned to either the CON: device
or to the TRM: device (see below for further details).
Output The primary output file. This file is assigned to either the CON: de-
vice or to the TRM: device (see below for further details)'
Can Assigned to the console device (CON :).
Trm Assigned to the terminal device (TRM :).
Kbd Assigned to the keyboard device (KBD:).
Lst Assigned to the list device (LST:).
Aux Assigned to the auxiliary device (AU X :).
Usr Assigned to the user device (USR:).
Notice that the use of Assign, Reset, Rewrite, and Close on these files is not
only unnecessary, but also illegal.
The logical device referred to by the standard files Input and Output is deter-
mined by the B compiler directive. The default value {$B+} causes the con-
sole device (CON:) to be used, which provides buffered input with editing fa-
cilities (see section 14.6.1 ), but it does not conform to the standard in all
aspects. I n the {$B -} mode, input and output will instead refer to the terminal
device (TRM:) which offers no editing facilities during input, but entries may
follow the formats defined by Standard, Pascal. No differences exist between
the console device and the terminal device on output operations.
Notice that the B compiler directive must be placed at the start of the pro-
gram block, and is thus a global directive which cannot be changed throug-
hout the program text. If some input/output operations are to use the CON:
device, and others the TRM: device, then set the B directive for the most fre-
quently used device and specify the other device explicitly in the remaining
calls to i/o procedures.
Example:
{$B- }
program ReadAndWri tee input, output);
Read(Kbd, Var)
As the standard files Input and Output are used very frequently, they are cho-
sen by default when no file identifier is explicitly stated. The following list
shows the abbreviated text file operations and their equivalents:
The following program shows the use of the standard file Lst to list the file
ProductFile (see the example on page 99 ) on the printer:
program ListProductFile;
const
MaXNumberOfProducts = 100;
type
ProductName = string[20];
Product = record
Name: ProductName; IterrNumber: Integer;
InStock: Real;
Suppl ier: Integer;
end;
Va.r
ProductFile: file of Product;
ProductRec: Product; I: Integer;
begin
Ass ign(ProductFi Ie, 'ffiOIXJCT. UI'A' ); Reset(ProductFi Ie);
for I := 1 to MaXNumberOfProducts do
begin
Read(ProductFile,ProductRec);
lJi th Produc tRec do
begin
i f Name< >" then
Writeln(Lst, 'Item: ',IterrNumber:5,' " Name:20,
From: " Supplier:5,
, Now in stock: ',InStock:0:0);
end;
end;
Close(ProductFile);
end.
Input and output of data in readable form is done through text files as descri-
bed in section 14.5. A text file may be assigned to any device, i.e. a disk file or
one of the standard I/O devices. Input and output on text files is done with the
standard procedures Read, Rea din, Write, and Writeln which use a special
syntax for their parameter lists to facilitate maximum flexibility of input and
output.
In particular, parameters may be of different types, in which case the I/O pro-
cedures provide automatic data conversion to and from the basic Char type of
text files.
The Read procedure provides input of characters, strings, and numeric data.
The syntax of the Read statement is:
where Var1, Var2, ... , VarN are variables of type Char, String, Integer or Real. In
the first case, the variables are input from the the standard file Input, usually
the keyboard. In the second case, the variables are input from the text file
which is previously assigned to FilVar and prepared for reading.
With a variable of type Char, Read reads one character from the file and as-
signs that character to the variable. If the file is a disk file, Eoln is true if the
next character is a CR or a Ctrl-Z, and Eof is true if the next character is a Ctrl-
Z, or physical end-of-file is met. If the file is a logical device (including the
standard files Input and Output), Eoln is true if the character read was a CR or
if Eof is True, and Eof is true if the character read was a Ctrl-Z.
A special case of numeric input is when Eoln or Eat is true at the begin-
ning of the Read (e.g. if input from the keyboard is only a CR). In that case no
new value is assigned to the variable, and the variable retains its former value.
If the input file is assigned to the console device (CON:)' or if the standard file
Input is used in the {$B+} mode (default), special rules apply to the reading of
variables. On a call to Read or Readln, a line is input from the console and
stored into a buffer, and the reading of variables then uses this buffer as the
input source. This allows for editing during entry. The following editing facili-
ties are available: .
Ctrl-X
Backspaces to the beginning of the line and erases all characters in-
put.
The RETURN key is used to terminate the input line. This key may be marked
ENTER on some keyboards. This terminating CR is not echoed to the screen.
Internally. the input line is stored with a Ctrl-Z appended to the end of it.
Thus. if fewer values are specified on the input line than the number of variab-
les in Reads parameter list. any Char variables in excess will be set to Ctrl-Z.
Strings will be empty. and numeric variables will remain unchanged.
The maximum number of characters that can be entered on an input line from
the console is 127 by default. However. you may lower this limit by assign-
ing an integer in the range 0 through 127 to the predefined variable BufLen.
Example:
Wri tee 'Fi Ie name (max. 14 chars): ,);
BufLen; = 14;
Read(Fi leName);
The Readln procedure is identical to the Read procedure. except that after the
last variable has been read. the remainder of the line is skipped. I.e., all cha-
racters up to and including the next CR/LF sequence (or the next CR on a logi-
cal device) are skipped. The syntax of the procedure statement is:
After a Rea dIn • the following Read or Readln will read from the beginning of
the next line. Readln may also be called without parameters:
Readln
or
Readln(FiIVar)
in which case the remaining of the line is skipped. When Readln is reading
from the console (standard file Input or a file assigned to CON:). the terminat-
ing CR is echoed to the screen as a CR/LF sequence. as opposed to Read.
where Var1, Var2, ... , VarN (the write parameters) are variables of type Char,
String, Boolean, Integer or Real, optionally followed by a colon and an integer
expression defining the width of the output field. In the first case, the variab-
les are output to the the standard file Output, usually the screen. In the se-
cond case, the variables are output to the text file which is previously assig-
ned to FilVar.
The format of a write parameter depends on the type of the variable. In the
following descriptions of the different formats and their effects, the symbols:
Writeln
or
Writeln{File)
Untyped files are low-level I/O channels primarily used for direct access to
any disk file using a record size of 128 bytes.
Var
DataFi Ie: fi Ie;
All standard file handling procedures and functions except Read, Write, and
Flush are allowed on untyped files. Read and Write are replaced by two spe-
cial high-speed transfer procedures: BloekRead and BloekWrite. The syntax of
a call to these procedures is:
where FilVar variable identifier of an untyped file, Var is any variable, and rees
is an integer expression defining the number of 128-byte records to be trans-
ferred between the disk file and the variable. The transfer starts at the first
byte occupied by the variable Var. The programmer must insure the program-
mer to insure that the variable Var occupies enough space to accomodate the
entire data transfer. A call to BloekRead or BloekWrite also advances the file
pointer rees records.
The standard function EOF works as with typed files. So do standard func-
tions FilePos and FileSize and standard procedure Seek, using a component
size of 128 bytes (the record size used by BlockRead and BlockWrite).
The following program shows the use of an untyped file. It reads any disk file
and copies its contents to any other disk file:
program Fi leCopy;
const
BufSize 200;
BufByteSize 15600;
var
Source,
Destination: Fi Ie;
SourceName,
DestinationName: string[14];
Buffer: arr~[1 .. BufByteSize] of Byte;
NoOfRecsToRead,
Remaining: Integer;
begin
Wri tee 'Enter source file name: ' );
Readln( SourceName);
Ass ign(Source, SourceName);
Reset (Source);
Write( 'Enter destination file name: ,);
Readln(DestinationName);
Assign(Dest inat ion, DestinationName);
Rewri te(Dest inat ion);
Remaining := FileSize(Source);
whi Ie Remaining > 0 do
begin
if BufSize <= Remaining then
NoOfRecsTaRead: =BufSize
else
NoOfRecsToRead: =Remaining;
B lockRead( Source, Buffer , NoOfRecsToRead) ;
BlockWrite(Destination,Buffer,NoOfRecsToRead);
Remaining : = Remaining-NoOfRecsToRead;
end;
Close(Dest inat ion);
end.
If I/O checking is passive, Le. {$I-}, no run time checks are performed. An I/O
error thus does not cause the program to stop, but suspends any further I/O
until the standard function 10resuit is called. When this is done, the error con-
dition is reset and I/O may be performed again. It is now the programmer's
responsibility to take proper action according to the type of I/O error. A zero
returned by 10resuit indicates a successful operation, anything else means
that an error occurred during the last I/O operation. Appendix I lists all error
messages and their Numbers. Notice that as the error condition is reset
when 10resuit is called, subsequent calls to 10resuit will return zero until the
next I/O error occurs.
Variables discussed up to now have been static, i.e. their form and size is pre-
determined, and they exist throughout the entire execution of the block in
which they are declared. Programs, however, frequently need the use of a
data structure which varies in form and size during execution. Dynamic va-
riables serve this purpose as they are generated as the need arises and may
be discarded after use.
Such dynamic variables are not declared in an explicit variable declaration like
static variables, and they cannot be referenced directly by identifiers. Instead,
a special variable containing the memory address of the variable is used to
point to the variable. This special variable is called a pointer variable.
The following shows how to declare a record with associated pointers. The
type Person Pointer is is declared as a pointer to variables of type PersonRe-
cord:
type
PersonPointer = ~PersotiRecord;
PersotiRecord = reco~
Name: string[ 50];
Job: string[50];
Next: PersonPointer;
end;
Var
FirstPerson, LastPerson, NewPerson: PersonPointer;
As shown above, the type identifier in a pointer type definition may refer to an
identifier which is not yet defined.
Before it makes any sense to use any of these pointer variables we must, of
course, have some variables to point at. New variables of any type are alloca-
ted with the standard procedure New. The procedure has one parameter
which must be a pointer to variables of the type we want to create.
New(Fi rstPerson);
which has the effect c'f having FirstPerson point at a dynamically allocated re-
cord of type Person Record.
The pointer value nil is compatible with all pointer types. nil points to no dy-
namic variable, and may be aS,signed to pointer variables to indicate the ab-
sence of a usable pointer. nil may also be used in comparisons.
Mark(Var);
where Var is a pointer variable. The Release procedure sets the heap pointer
to the address contained in its argument. The syntax is:
Re 1ease(Var);
where Var is a pointer variable, previously set by Mark. Release thus discards
all dynamic variables above this address. It is not possible to release the
space used by variables in the middle of the heap.
procedure Jobsj
type
PersonPointer = ~PersonRecordj
PersonRecord = record
Name: strin.g[50];
Job: strin.g[ 50];
Next: PersonPointerj
endj
Var
HeapTop: ~ Integerj
FirstPerson, LastPerson, NewPerson: PersonPointerj
Name: strin.g[50] j
begin
Fi rstPerson : = ni 1;
Mark(HeapTop) ;
repeat
Wri tee 'Enter name: ' );
Readln(Name);
if Name <> " then
begfn
New(NewPerson) ;
NewPerson~ . Name . - Name;
Write( 'Enter profession: ,);
Readln(NewPerson~.Job)j
Wri teln;
if FirstPerson = nil then
Fi rstPerson : = NewPerson
else
LastPerson~ . Next : = NewPerson;
LastPerson : = NewPerson;
LastPerson~ . Next : = ni 1;
end;
until Name = , ';
Wri telnj
while FirstPerson <> nil do
with FirstPerson~ do
begin
Write In(Name , ' is a ',Job);
FirstPerson := Next;
end;
Re lease(HeapTop) j
end.
The standard procedure GetMem is used to allocate space on the heap. Un-
like New, which allocates as much space as required by the type pointed to
by its argument, GetMem allows the programmer to control the amount of
space allocated. GetMem is called with two parameters:
GetMem(PVar, 1)
where PVar is any pointer variable, and I is an integer expression giving the
number of bytes to be allocated.
Notes:
A Pascal program consists of one or more blocks, each of which may again
consist of blocks, etc. One such block is a procedure, another is a function (in
common called subprograms). Thus, a procedure is a separate part of a pro-
gram, and it is activated from elsewhere in the program by a procedure state-
ment (see section 7.1.2). A function is rather similar, but it computes and re-
turns a value when its identifier, or designator, is encountered during execu-
tion (see section 6.2).
16.1 Parameters
When parameters are passed by value, the formal parameter represents a lo-
cal variable in the subprogram, and changes of the formal parameters have no
effect on the actual parameter. The actual parameter may be any expression,
including a variable, with the same type as the corresponding formal parame-
ter. Such parameters are called a value parameter and are declared in the
subprogram heading as in the following example. (This and the following ex-
amples show procedure headings; function headings are slightly different as
described i section 1 6.3.1 .)
Number and Txt are previously defined types (e.g. Integer and string[255]),
and Num1, Num2, Str1, and Str2 are the formal parameters to which the va-
lue of the actual parameters are passed. The types of the formal and the ac-
tual parameters must correspond.
Notice that the type of the parameters in the parameter part must be speci-
fied as a previously defined type identifier. Thus, the construct:
is not allowed. Instead, the desired type should be defined in the type defini-
tion of the block, and the type identifier should then be used in the parameter
declaration:
type
Range arr~[ 1 .. 500] of Integer;
Value parameters and variable parameters may be mixed in the same proce-
dure as in the following example:
in which Num1 and Num2 are variable parameters and Stf1 and Str2 are va-
lue parameters.
All address calculations are done at the time of the procedure call. Thus, if a
variable is a component of an array, its index expression(s) are evaluated
when the subprogram is called.
Normally, when using variable parameters, the formal and the actual parame-
ters must match exactly. This means that subprograms employing variable
parameters of type String will accept only strings of the exact length defined
in the subprogram. This restriction may be overridden by the V compiler di-
rective. The default active state {$V+} indicates strict type checking, whereas
the passive state { $V -} relaxes the type checking and allows actual parame-
ters of any string length to be passed, irrespective of the length of the formal
parameters.
Example:
program NSA;
{this program must be compiled with the $V- directive}
{$V- }
type
WorkString = string[255];
Var
Line1: string[80];
Line2: string[ 100] ;
procedure Encode(Var LineToEncode: WorkString);
Var I: Integer;
begin
for I := 1 to Length(LineToEncode) do
LinetoEncode[I] := Chr(Ord(LineToEncode[I])-30);
end;
begin
Line1 .- 'This is a secret message';
Encode(Line1) ;
Line2 := 'Here is another (longer) secret message';
Enc ode (L ine2);
end.
If the type of a formal parameter is not defined, i.e. the type definition is omit-
ted from the parameter section of the subprogram heading, then that parame-
ter is said to be untyped. Thus, the corresponding actual parameter may be
any type.
The untyped formal parameter itself is incompatible with all types, and it may
therefore be used only in contexts where the data type is of no significance,
e.g. as a parameter to Addr, BlockRead/Write, Fil/Char, or Move, or as the ad-
dress specification of absolute variables.
The Switch Var procedure in the following example demonstrates the use of
untyped parameters. It moves the contents of the variable A1 to A2 and the
contents of A2 to A 1 .
type
Matrix = arrayL1.. 50,1. .25] of Real;
Var
TestMatrix,BestMatrix: Matrix;
then Switch Var may be used to switch values between the two matrices:
SwitchVar(TestMatrix,BestMatrix, SizeOf(Matrix));
16.2 Procedures
Examples:
procedure Logon;
procedure Position(X,Y: Integer);
procedure Compute(Var Data: Matrix; Scale: Real);
The declaration part of a procedure has the same form as that of a program.
All identifiers declared in the formal parameter list and the declaration part
are local to that procedure, and to any procedures within it. This is called the
scope of an identifier, outside which they are not known. A procedure may
reference any constant, type, variable, procedure, or function defined in an
outer block.
The statement part specifies the action to be executed when the the proce-
dure is invoked, and it takes the form of a compound statement (see section
7.2.1). If the procedure identifier is used within the statement part of the pro-
cedure itself, the procedure will ex'ecute recursively. (CP/M -80 only: Notice
that the A compiler directive must be passive { $A-} when recursion is used,
see appendix E .)
The next example shows a program which uses a procedure and passes a pa-
rameter to this procedure. As the actual parameter passed to the procedure is
in some instances a constant (a simple expression), the formal parameter
must be a value parameter.
program Box;
Var
I: Integer;
procedure DrawBox(Xl ,Yl, X2, Y2: Integer);
Var I: Integer;
begin
GotoXY(Xl ,Yl);
for I := Xl to X2 do write('-');
GotoXY(Xl ,Yl+l);
f or I : = Yl + 1 to Y2 do
begin
GotoXY(Xl,1); Write('!');
GotoXY(X2,1); Write('!');
end;
GotoXY(Xl ,Y2);
for I := Xl to X2 do Write( ,-,);
end; { of procedure DrawBox }
begin
C lrScr;
for I := 1 to 5 do DrawBox(I*4,I*2,10*I,4*I);
DrawBox(1,1,80,23);
end.
Often the changes made to the formal parameters in the procedure should
also affect the actual parameters. In such cases variable parameters are used,
as in the following example:
Switch(I,J);
i.e. with a value parameter, then the statement Swi tch( I, J) would not
change I and J.
16.2.2.1 ClrEol
Syntax: ClrEol
Clears all characters from the cursor position to the end of the line without
moving the cursor.
16.2.2.2 CIrScr
Syntax: ClrScr
Clears the screen and places the cursor in the upper left-hand corner. Beware
that some screens also reset the video-attributes when clearing the screen,
possibly disturbing any user-set attributes.
Syntax: Crtlnit
Sends the Terminal Reset String defined in the installation procedure to the
screen.
16.2.2.5 Delay
Syntax: Delay(Time)
The Delay procedure creates a loop which runs for approx. as many millise-
conds as defined by its argument Time which must be an integer. The exact
time may vary somewhat in different operating environments.
16.2.2.6 Delline
Syntax: DelLine
Deletes the line containing the cursor and moves all lines below one line up.
Inserts an empty line at the cursor position. All lines below are moved one line
down and the bottom line scrolls off the screen.
16.2.2.8 GotoXY
Syntax: GotoXY(Xpos, Ypos)
Moves the cursor to the position on the screen specified by the integer ex-
pressions Xpos (horizontal value, or row) and Ypos (vertical value, or column).
The upper left corner (home position) is (1,1).
16.2.2.9 LowVideo
Syntax: LowVideo
Sets the screen to the video attribute defined as 'Start of Low Video' in the in-
stallation procedure, i.e. 'dim' characters.
Syntax: NormVideo
Sets the screen to the video attribute defined as 'Start of Normal Video' in the
installation procedure, i.e. the 'normal' screen mode.
16.2.2.11 Randomize
Syntax: Randomize
16.2.2.12 Move
Syntax: Move(var1,var2,Num}
Does a mass copy directly in memory of a specified number of bytes. var1 and
var2 are two variables of any type, and Num is an integer expression. The pro-
cedure copies a block of Num bytes, starting at the first byte occupied by var1
to the block starting at the first byte occupied by var2. You may notice the ab-
sence of explicit 'moveright' and 'moveleft' procedures. This is because Move
automatically handles possible overlap during the move process.
16.2.2.13 Fil/Char
a
Fills a range of memory with a given value. Var is variable of any type, Num
is an integer expression, and Value is an expression of type Byte or Char. Num
bytes, starting at the first byte occupied by Var, are filled with the value Value.
16.3 Functions
The function heading is equivalent to the procedure heading, except that the
heading must define the type of the function result. This is done by adding a
colon and a type to the heading as shown here:
The result type of a function must be a scalar type (i.e. Integer, Real, Boolean,
Char, declared scalar or subrange), a string type, or a pointer type.
The following example shows the use of a function to compute the sum of a
row of integers from I to J.
{$A- }
program Factorial;
Va.r Number: Integer;
function FactorialCValue: Integer): Real;
begin
if Value = 0 then Factorial := 1
else Factorial : = Value * FactorialCvalue-l);
end;
begin
Read(Number) ;
Writeln(~M,Number,' ! ',FactorialCNumber) );
end.
Note that the type used in the definition of a function type must be previously
specified as a type identifier. Thus, the construct:
is not allowed. Instead, a type identifier should be associated with the type
stringf80J, and that type identifier should then be used to define the function
result type, e.g.:
type
Str80 = string[ 80];
16.3.2.1.1 Abs
Returns the absolute value of Num. The argument Num must be either Real
or Integer, and the result is of the same type as the argument.
16.3.2.1.2 ArcTan
Returns the angle, in radians, whose tangent is Num. The argument X must
be either Real or Integer, and the result is Real.
16.3.2.1.3 Cos
Returns the cosine of Num. The argument Num is expressed in radians, and
its type must be either Real or Integer. The result is of type Real.
16.3.2.1.4 Exp
Returns the exponential of Num, i.e. enum . The argument Num must be either
Real or Integer, and the result is Real.
16.3.2.1.5 Frac
Returns the fractional part of Num, i.e. Frac( Num) =Num - Int( Num). The
argument Num must be either Real or Integer, and the result is Real.
16.3.2.1.6 Int
Returns the integer part of Num, i.e. the greatest integer number less than or
equal to Num, if Num ) = 0, or the smallest integer number greater than or
equal to Num, if Num < O. The argument Num must be either Real or Integer,
and the result is Real.
16.3.2.1.7 Ln
Returns the natural logarithm of Num. The argument Num must be either
Real or Integer, and the result is Real.
16.3.2.1.8 Sin
Returns the sine of Num. The argument Num is ~xpressed in radians, and its
type must be either Real or Integer. The result is of type Real.
16.3.2.1.9 Sqr
Returns the square of Num, i.e. Num~ Num. The argument Num must be eit-
her Real or Integer, and the result is of the same type as the argument.
16.3.2.1.10 Sqrt
Returns the square root of Num. The argument Num must be either Real or
Integer, and the result is Real.
16.3.2.2.1 Pred
Returns the predecessor of Num (if it exists). Num is of any scalar type.
16.3.2.2.2 Succ
Returns the successor of Num (if it exists). Num is of any scalar type.
16.3.2.2.3 Odd
Returns boolean True is Num is an odd number, and False if Num is even.
Num must be of type Integer.
The transfer functions are used to convert values of one scalar type to that of
another scalar type. In addition to the following functions, the retype facility
described in section 8.3 serves this purpose.
16.3.2.3.1 Chr
Returns the character with the ordinal value given by the integer expression
Num. Example: Chr(65) returns the character 'A'.
16.3.2.3.2 Ord
Returns the ordinal number of the value Var in the set defined by the type Var.
Ord{Var) is equivalent to Integer{Var) (see Type Conversiions in section 8.3 .
Var may be of any scalar type, except Real, and the result is of type Integer.
16.3.2.3.3 Round
16.3.2.3.4 Trunc
=
Returns the greatest integer less than or equal to Num, if Num > 0, or the
smallest integer greater than or equal to Num, if.,Num < O. Num must be of
type Real, and the result is of type Integer.
16.3.2.4.1 Hi
Syntax: Hi( t)
The low order byte of the result contains the high order byte of the value of
the integer expression I. The high order byte of the result is zero. The type of
the result is Integer
16.3.2.4.2 KeyPressed
Syntax: KeyPressed
Returns boolean True if a key has been pressed at the console, and False if no
key has been pressed. The result is obtained by calling the operating system
console status routine.
16.3.2.4.3 Lo
Syntax: Lo( t)
Returns the low order byte of the value of the integer expression I with the
high order byte forced to zero. The type of the result is Integer.
16.3.2.4.4 Random
Syntax: Random
Returns a random number greater than or equal to zero and less than one.
The type is Real.
Returns a random number greater than or equal to zero and less than Num.
Num and the random number are both Integers.
16.3.2.4.6 SizeOf
16.3.2.4.7 Swap
The Swap function exchanges the high and low order bytes of its integer ar-
gument Num and returns the resulting value as an integer.
16.3.2.4.8 UpCase
Example:
program Catch22;
Var
X: Integer;
funct ion Up(Var I: Integer): Integer; forward;
funct ion Down(Var I: Integer): Integer;
begin
I := I div 2; Writeln(I);
if I <> 1 then I := Up(I);
end;
funct ion Up;
begin
while I mod. 2 <> 0 do
begin
I := 1*3+1; Writeln(1);
end;
I : = Down( 1) ;
end;
begin
Write( 'Enter any integer: ,);
Readln(X);
X := Up(X);
Write( 'Ok. Program stopped again. ,);
end.
3
10
5
16
8
4
2
1
Ok. Program stopped again.
program Catch222;
Var
X: Integer;
begin
Write( 'Enter any integer: ,);
Readln(X) ;
while X <> 1 do
begin
if X mod. 2 0 tben X .- X div 2 else X .- X*3+1;
Wri te In(X);
end;
Write( 'Ok. Program stopped again. ,);
end.
It may interest you to know that it cannot be proved if this small and very
simple program actually will stop for any integer!
Notes:
The fact that the TURBO editor performs editing only within memory limits
the size of source code handled by the editor. The I compiler directive can be
used to circumvent this restriction, as it provides the ability to split the source
code into smaller 'lumps' and put it back together at compile-time. The in-
clude facility also aids program clarity, as commonly used subprograms, once
tested and debugged, may be kept as a 'library' of files from which the
necessary files can be included in any other program.
{$I f i 1ename }
where filename is any legal file name. Spaces are ignored and lower case let-
ters are translated to upper case. If no file type is specified, the default type
.PAS is assumed. This directive must be specified on a line by itself.
Exampes:
{$I firs t . pas}
{$i StdProc}
{$I COMPUTE. MOD}
To demonstrate the use of the include facility, let us assume that in your 'li-
brary' of commonly used procedures and functions you have a file called
STUPCASE.FUN. It contains the function StUpCase which is called with a
character or a string as parameter and returns the value of this parameter
with any lower case letters set to upper case.
File STUPCASE.FUN:
In any future program you write which requires this function to convert strings
to upper case letters, you need only include the file at compile-time instead of
duplicating it into the source code:
This method not only is easier and saves space; it also makes the task of
keeping programs updated quicker and safer, as any change to a 'library' rou-
tine will automatically affect all programs including this routine.
Notice that TURBO Pascal allows free ordering, and even multiple occur-
rences, of the individual sections of the declaration part. You may thus e.g.
have a number of files containing various commonly used type definitions in
your 'library' and include the ones required by different programs.
All compiler directives except Band C are local to the file in which they ap-
pear, i.e. if a compiler directive is set to a different value in an included file, it
is reset to its original value upon return to the including file. Band C directi-
ves are always global. Compiler directives are described in appendix E .
Include files cannot be nested, i.e. one include file cannot include yet another
file and then continue processing.
A. CP/M-SO
This appendix describes features of TURBO Pascal specific to the 8-bit imple-
mentation. It presents two kinds of information:
1) Things you must know to make efficient use of TURBO Pascal. These are
described in section A.l .
2) The remaining sections describe things which are only of interest to expe-
rienced programmers, e.g. calling machine language routines, technical
aspects of the compiler, etc.
The 0 command selects the following menu on which you may view and
change some default values of the compiler. It also provides a helpful function
to find runtime errors in programs compiled into object code files.
The three commands M, C, and H select the compiler mode, i.e. where to put
the code which results from the compilation.
Memory is the default mode. When active, code is produced in memory and
resides there ready to be activated by a Run command.
CP/M-80 143
A.1.1 Memory / Com file / c Hn -file
When Com or cHn mode is selected, the menu is expanded with the follow-
ing two lines:
The use of these additional commands are explained in sections A.1.2 and
A.1.3.
The Start address specifies the address (in hexadecimal) of the first byte of
the code. This is normally the end address of the Pascal library plus one, but
may be changed to a higher address if you want to set space aside e.g. for
absolute variables to be shared by a series of chained programs.
When you enter an 5, you are prompted to enter a new Start address. If you
just hit <RETURN>, the minimum value is assumed. Don't set the Start ad-
dress to anything less than the minimum value, as the code will then over-
write part of the Pascal library.
The End address specifies the highest address available to the program (in
hexadecimal). The value in parentheses indicate the top of the TPA on your
computer, i.e. BOOS minus one. The default setting is 700 to 1000 bytes less
to allow space for the loader which resides just below BOOS when executing
programs from TURBO.
When you enter an E, you are prompted to enter a End address. If you just hit
(RETURN), the default value is assumed (j.e. top of TPA less 700 to 1000
bytes). If you set the End address higher than this, the resulting programs
cannot be executed from TURBO, as they will overwrite the TURBO loader;
and if you set it higher than the TPA top, the resulting programs will over-
write part of BOOS if run on your machine.
When you run a program compiled in memory, and a runtime error occurs, the
editor is invoked, and the error is automatically pointed out. This, of course, is
not possible if the program is in a .COM file or an .CHN file. Run time errors
then print out the error code and the value of the program counter at the time
of the error, e.g.:
To find the place in the source text where the error occurred, enter the F com-
mand on the Options menu. When prompted for the address, enter the ad-
dress given by the error message:
CP/M-80 145
A.1A Find Runtime Error
Ent e r PC:-1B5.Q.
The place in the source text is now found and pointed out exactly as if the er-
ror had occurred while running the program in memory.
The following standard identifiers are unique to the CP/M -80 implementa-
tion:
Example:
var
IObyte: Byte absolute $0003;
CmdLine: string[127] absolute $80;
Absolute may also be used to declare a variable "on top" of another variab-
le, i.e. that a variable should start at the same address as another variable.
When absolute is followed by the variable (or parameter) identifier, the new
variable will start at the address of that variable (or parameter).
Example:
var
Str: string[32];
StrLen: Byte absolute Str;
The above declaration specifies that the variable StrLen should start at the
same address as the variable Str, and since the first byte of a string variable
gives the length of the string, StrLen will contain the length of Str. Notice that
only one identifier may be specified in an absolute declaration, i.e. the cons-
truct
is illegal. Further details on space allocation for variables are given in sections
A.1 5 and A.1 6 .
Returns the address in memory of the first byte of the type, variable, pro-
cedure, or function with the identifier name. If name is an array, it may be
subscribed, and if name is a record, specific fields may be selected. The value
returned is of type Integer.
TURBO Pascal offers two predefined arrays of type Byte, called Mem and
Port, which are used to directly access CPU memory and data ports.
Example:
Mem[WsCursor] . - 2;
Mem[WsCursor+l1 := $lB;
Mem[WsCursor+2] : = Orde' -, );
IObyte : = Mem[ 3];
Mem[Addr+Of f set] : = Mem[Addr];
CP/M-80 147
A.5.2 Port Array
The use of the port array is restricted to assignment and reference in ex-
pressions only, i.e. components of Port cannot function as variable parame-
ters to procedures and functions. Furthermore, operations referring to the en-
tire Port array (reference without index) are not allowed.
The X compiler directive allows the programmer to select whether array sub-
scription should be optimized with regard to execution speed or to code size.
The default mode is active, i.e. {$X+l, which causes execution speed op-
timization. When passive, i.e. {$X-l, the code size is minimized.
A.B.t MemAvail
The standard function MemAvail is available to determine the available space
on the heap at any given time. The result is an Integer, and if more than
32767 bytes is available, MemAvail returns a negative number. The correct
number of free bytes is then calculated as 65536.0 + MemAvail. Notice the
use of a real constant to generate a Real result, as the result is greater than
GMaxlnt. Memory management is discussed in further detail in section A.16 .
The reserved word external is used to declare external procedures and func-
tions, typically procedures and functions written in machine code.
TURBO Pascal provides two standard procedures: Chain and Execute which
allow you to activate other programs from a TURBO program. The syntax of
these procedure calls is:
Chain(Fi lVar)
Execute (Fi lVar)
CP/M-BO 149
A.10 Chain and Execute
where FilVar is a file variable of any type, previously assigned to a disk file
with the standard procedure Assign. If the file exists, it is loaded into memory
and executed.
The Chain procedure is used only to activate special TURBO Pascal .CHN fi-
les, i.e. files compiled with the cH n-file option selected on the Options menu
(see section A.1.1 ). Such a file contains only program code; no Pascal library.
It is loaded into memory and executed at the start address of the current pro-
gram, i.e. the address specified when the current program was compiled. It
then uses the Pascal library already present in memory. Thus, the current pro-
gram and the chained program must use the same start address.
The Execute procedure may be used to execute any .COM file, i.e. any file
containing executable code. This could be a file created by TURBO Pascal
with the Com-option selected on the Options menu (see section A.1.1 ). The
file is loaded and executed at address $1 00, as specified by the CP/M stan-
dard.
If the disk file does not exist, an I/O error occurs. This error is treated as de-
scri-bed in section 14.8 . If the I compiler directive is passive ({ $I-}), program
execution continues with the statement following the failed Chain or Execute
statement, and the IOresult function must be called prior to further I/O.
Data can be transferred from the current program to the chained program ei-
ther by shared global variables or by absolute address variables.
Example:
Program MAIN. COM:
program Main;
var
Txt: string[ 80] ;
CntPrg: file;
begin
Wri tee 'Enter any text: ,); Readln(Txt);
As s i gn( CntPrg, 'ChrCount . chn' ) ;
Chain(CntPrg) ;
end.
Program CHRCOUNT.CHN:
program ChrCount;
var
Txt: string[ 80] ;
NoOfChar,
NoOfUpc,
I: Integer;
begin
NoOfUpc . - 0;
N00 fChar : = Lengt h( Txt) ;
for I := 1 to length(Txt) do
if Txt [I] in [ 'A' .. 'Z'] tben NoOfUpc . - Succ(NoOfUpc);
Wri tee 'No of characters in entry: ',NoOfChar);
Writeln( '. No of upper case characters: " NoOfUpc, '. ,);
end.
Note that neither Chain nor Execute can be used in direct mode, i.e. from a
program run with the compiler options switch in position Memory (section
A.1.1 ).
CP/M-80 151
A.11 In -line Machine Code
TURBO Pascal features the inline statements as a very convenient way of in-
serting machine code instructions directly into the program text. An inline sta-
tement consists of the reset:Ved word inline followed by one or more con-
stants, variable identifiers, or location counter references, separated by slash-
es and enclosed in parentheses.
The constants may be either literal constants or constant identifiers, and they
must be of type Integer. Literals generate one byte of code if within the range
0 .. 255 ($00 .. $FF). otherwise two bytes in the standard byte reversed format.
Constant identifiers always generate two bytes of code.
A variable identifier generates two bytes of code (in byte reversed format)
containing the memory address of the variable.
Inline statements may be freely mixed with other statements throughout the
statement part of a block, and inline statements may use all CPU registers.
Note, however, that the contents of the stack pointer register (SP) must be
the same on exit as on entry.
For the purpose of calling CP/M BOOS and BIOS routines, TURBO Pascal
introduces two standard procedures: Bdos and Bios, and four standard func-
tions: Bdos, BdosHL, Bios, and BiosHL.
Details on BOOS and BIOS routines are found in the CP/M Operating System
Manual published by Digital Research.
The Bdos procedure is used to invoke CP/M BOOS routines. Func and Pa-
ram are integer expressions. Func denotes the number of the called routine
and is loaded into the C register. Param is optional and denotes a parameter
which is loaded into the DE register pair. A call to address 5 then invokes the
BOOS.
The Bdos function is called like the procedure and returns an Integer result
which is the value returned by the BOOS in the A register.
This function is exactly similar to the Bdos function above, except that the re-
sult is the value returned in the H L register pair.
CP/M-80 153
A.T 2.3 Bios procedure and function
The Bios procedure is used to invoke 810S routines. Func and Param are in-
teger expressions. Func denotes the number of the called routine, with 0
meaning the W800T routine, 1 the CONST routine, etc. I.e. the address of
*
the called routine is Func 3 plus the W800T address contained in address-
es 1 and 2. Param is optional and denotes a parameter which is loaded into
the 8C register pair prior to the call.
The Bios function is called like the procedure and returns an integer result
which is the value returned by the 8 lOS in the A register.
This function is exactly similar to the Bios function above, except that the re-
sult is the value returned in the HL register pair.
For some applications it is practical for a programmer to define his own input
and output drivers, i.e. routines which perform input and output of characters
to and from external devices. The following drivers are part of the TURBO
environment, and used by the standard I/O drivers (although they are not
available as standard procedures or functions):
The ConSt routine is called by the function KeyPressed, the Conln and Con-
Out routines are used by the CON:, TRM:, and KBD: devices, the LstOut rou-
tine is used by the LST: device, the AuxOut and Auxin routines are used by
the AUX: device, and the UsrOut and Usrln routines are used by the USR: de-
vice.
By default, these drivers use the corresponding BIOS entry points of the
CP/M operating system, i.e. ConSt uses CONST, Conln uses CONIN, ConOut
uses CONOUT, LstOut uses LIST, AuxOut uses PUNCH, Auxin uses READER,
UsrOut uses CONOUT, and Usrln uses CONIN. This, however, may be chan-
ged by the programmer by assigning the address of a self-defined driver pro-
cedure or a driver function to one of the following standard variables:
A user defined driver procedure or driver function must match the definitions
given above, i.e. a ConSt driver must be a Boolean function, a Conln driver
must be a Char function, etc.
CP/M-80 155
A.14 Interrupt Handling
The TURBO Pascal run time package and the code generated by the compiler
are both fully interruptible. Interrupt service routines must preserve all regi-
sters used.
The general rules for register usage are that integer operations use only the
AF, BC, DE, and HL registers, other operations may use IX and IY, and real
operations use the alternate registers.
An interrupt service procedure should not employ any I/O operations using
the standard procedures and functions of TURBO Pascal, as these routines
are not re-entrant. Also note that BOOS calls (and in some instances BIOS
calls, depending on the specific CP/M implementation) should not be per-
formed from interrupt handlers, as these routines are not re-entrant.
The programmer may disable and enable interrupts throughout a program us-
ing 01 and EI instructions generated by inline statements.
In the following descriptions, the symbol @ denotes the address of the first
byte occupied by a variable of the given type. The standard function Addr may
be used to obtain this value for any variable.
The basic data types may be grouped into structures (arrays, records, and disk
files), but this structuring will not affect their internal formats.
A.15.T.T Scalars
The following scalars are all stored in a single byte: Integer subranges with
both bounds in the range 0 .. 255, Booleans, Chars, and declared scalars with
less than 256 possible values. This byte contains the ordinal value of the va-
riable.
The following scalars are all stored in two bytes: Integers, Integer subranges
with one or both bounds not within the range 0 .. 255, and declared scalars
with more than 256 possible values. These bytes contain a 2's complement
16-bit value with the least significant byte stored first.
A.15.T.2 Reals
Reals occupy 6 bytes, giving a floating point value with a 40-bit mantissa and
an 8-bit 2's exponent. The exponent is stored in the first byte and the man-
tissa in the next five bytes which the least significant byte first:
@ Exponent
@+1 LSB of mantissa
@ +5 MSB of mantissa
The exponent uses binary format with an offset of $80. Hence, an exponent
of $84 indicates that the value of the mantissa is to be multiplied by 2 ($84-
ft
$80) = 2 4 = 16. If the exponent is zero, the floating point value is conside-
ft
red to be zero.
CP/M-80 157
A.15.1.2 Reals
The value of the mantissa is obtained by dividing the 40-bit unsigned integer
by 2 40. The mantissa is always normalized, i.e. the most significant bit (bit 7
A
of the fifth byte) should be interpreted as a 1. The sign of the mantissa is sto-
red in this bit, a 1 indicating that the number is negative, and a 0 indicating
that the number is positive.
A.15.1.3 Strings
A string occupies the number of bytes corresponding to one plus the maxi-
mum length of the string. The first byte contains the current length of the str-
ing. The following bytes contain the actual characters, with the first character
stored at the lowest address. In the table shown below, L denotes the current
length of the string, and Max denotes the maximum length:
@ +L Last character
@ +L+1 Unused
@+Max Unused
A.15.1.4 Sets
An element in a set occupies one bit, and as the maximum number of ele-
ments in a set is 256, a set variable will never occupy more than 32 bytes
(256/8).
If a set contains less than 256 elements, some of the bits are bound to be
zero at all times and need therefore not be stored. In terms of memory effi-
ciency, the best way to store a set variable of a given type would then be to
"cut off" all insignificant bits, and rotate the remaining bits so that the first
element of the set would occupy the first bit of the first byte. Such rotate ope-
rations, however, are quite slow, and TURBO therefore employs a compro-
mise: Only bytes which are statically zero (Le. by'tes of which no bits are used)
are not stored. This method of compression is very fast and in most cases as
memory efficient as the rotation method.
BitAddress = E mod 8
Each file variable in a program has an associated file interface block (FIB). An
FIB occupies 176 bytes of memory and is divided into two sections: The con-
trol section (the first 48 bytes), and the sector buffer (the last 128 bytes). The
control section contains various information on the disk file or device cur-
rently assigned to the file. The sector buffer is used to buffer input and output
from and to the disk file.
@ Flags byte
@ +1 File type
@+2 Character buffer
@+3 Sector buffer pointer
@+4 Number of records (LSB)
@+5 Number of records (MSB)
@+6 Record length in bytes (LSB)
@+7 Record length in bytes (MSB)
@+8 Current record number (LSB)
@+9 Current record number (MSB)
@ +10 Unused (reserved)
@+11 Unused (reserved)
@ +12 First byte of CP/M FCB
CP/M-80 159
A.15.1.5 File Interface Blocks
The flags byte at @ contains four one bit flags which indicate the current sta-
tus of the file:
The file type field at@ +1 specifies the type of device currently assigned to the
file variable. The following values can occur:
When a file is assigned to a logical device, only the first three bytes of the FIB
are of significance.
The sector buffer pointer at@ +3 contains an offset from the first byte of the
sector buffer. The following three fields are used only by random access files
(defined files) and untyped files. Each field consists of two bytes in byte rever-
sed format. Bytes@ +10 and@ +11 are currently unused, but reserved for fu-
ture expansion. Bytes@ +12 through@ +47 contain a CP/M file control block
(FCB). The last block of the FIB is the sector buffer used for buffering input
and output from and to disk files.
The FIB format described above applies to all defined files and textfiles. The
FIB of an untyped file has no sector buffer, as data is transferred directly be-
tween a variable and the disk file. Thus, the length of the FIB of an untyped
file is only 48 bytes.
A.1S.1.6 Pointers
A.15.2.1 Arrays
The components with the lowest index values are stored at the lowest me-
mory address. A multi-dimensional array is stored with the rightmost dimen-
sion increasing first, e.g. given the array
Board!1,81
Board!2,11
Board!2,21
A.15.2.2 Records
The first field of a record is stored at the lowest memory address. If the record
contains no variant parts, the length is given by the sum of the lengths of the
individual fields. If a record contains a variant, the total number of bytes occu-
pied by the record is given by the length of the fixed part plus the length of
largest of its variant parts. Each variant starts at the same memory address.
CP/M-80 161
A.15.2.3 Disk Files
Disk files are different from other data structures in that data is not stored in
internal memory but in a file on an external device. A disk file is controlled th-
rough a file interface block (FIB) as described in section A.15.1.5. In general
there are two different types of disk files: random access files and text files.
A random access file consists of a sequence of records, all of the same length
and same internal format. To optimize file storage capacity, the records of a
file are totally contiguous. The first four bytes of the first sector of a file con-
tains the number of records in the file and the length of each record in bytes.
The first record of the file is stored starting at the fourth byte.
The basic components of a text file are characters, but a text file is subdivided
into lines. Each line consists of any number of characters ended by a CR/LF
sequence (ASCII $OD/$OA). The file is terminated by a Ctrl-Z (ASCII $1 B).
A.15.3 Parameters
Parameters are transferred to procedures and functions via the Z-80 stack.
Normally, this is of no interest to the programmer, as the machine code gene-
rated by TURBO Pascal will automatically PUSH parameters onto the stack
before a call, and POP them at the beginning of the subprogram. However, if
the programmer wishes to use external subprograms, these must POP the
parameters from the stack themselves.
On entry to an external subroutine, the top of the stack always contains the
return address (a word). The parameters, if any, are located below the return
address, i.e. at higher addresses on the stack. Therefore, to access the para-
meters, the subroutine must first POP off the return address, then all the pa-
rameters, and finally it must restore the return address by PUSHing it back
onto the stack.
With a variable (VAR) parameter, a word is transferred on the stack giving the
absolute memory address of the first byte occupied by the actual parameter.
With value parameters, the data transferred on the stack depends upon the
type of the parameter as described in the following sections.
A.1S.3.2.1 Scalars
Integers, Booleans, Chars and declared scalars (i.e. all scalars except Reals)
are transferred on the stack as a word. If the variable occupies only one byte
when it is stored, the most significant byte of the parameter is zero. Normally,
a word is POPped off the stack using an instruction like POP HL.
A.1S.3.2.2 Reals
A real is transferred on the stack using six bytes. If these bytes are POPped
using the instruction sequence:
IDP HL
IDP DE
IDP BC
then L will contain the exponent, H the fifth (least significant) byte of the
mantissa , E the fourth byte, 0 the third byte, C the second byte, and B the
first (most significant) byte.
CP/M-80 163
A.15.3.2.3 Strings
A.1S.3.2.3 Strings
When a string is at the top of the stack, the byte pointed to by SP contains the
length of the string. The bytes at addresses SP+1 through SP+n (where n is
the length of the string) contain the string with the first character stored at the
lowest address. The following machine code instructions may be used to POP
the string at the top of the stack and store it in StrBuf
ill DE,StrBuf
ill HL,0
ill B,H
ADD HL,SP
ill C, (HL)
INC 00
illIR
ill SP,HL
A.1S.3.2.4 Sets
A set always occupies 32 bytes on the stack (set compression only applies to
the loading and storing of sets). The following machine code instructions may
be used to POP the set at the top of the stack and store it in SetBuf
This will store the least significant byte of the set at the lowest address in
SetBuf
A.1S.3.2.S Pointers
Even when used as value parameters, Array and Record parameters are not
actually PUSHed onto the stack. Instead, a word containing the address of
the first byte of the parameter is transferred. It is then the responsibility of the
subroutine to POP this word, and use it as the source address in a block copy
operation.
Values of scalar types, except Reals, must be returned in the H L register pair.
If the type of the result is expressed in one byte, then it must be returned in L
and H must by zero.
Reals must be returned in the BC, DE, and HL register pairs. B, C, 0, E, and H
must contain the mantissa (most significant byte in B), and L must contain the
exponent.
Strings and sets must be returned on the top of the stack on the formats
described in sections A.1 5.3.2.3 and A.1 5.3.2.4.
CP/M-80 165
A.16 Memory Management
0000
CP/M and run-time workspace
Pascal Library
CP/M
HighMem
Figure A-5: Memory map during compilation in memorv
If the error message file is not loaded when starting TURBO, the source text
starts that much lower in memory. When the compiler is invoked, it generates
object code working upwards from the end of the source text. The CPU stack
works downwards from the logical top of memory, and the compiler's symbol
table works downwards from an address 1 K ($400 bytes) below the logical
top of memory.
0000
CP/M and run-time workspace
Pascal Library
Source text
CP/M
HighMem
CP/M-80 167
A.16.1.3 Execution in Memory
0000
CP/M and run-time workspace
Pascal Library
Source text
t- - - - - -- - - -- - - - - - - - ---
Object code
- - - - - - --
i - Recursion
- --
stack growing downward
- - - --
Default initial value of RecurPtr - - - --
'- ______ .___________ __ J__ _ CPU stack growing downward
Default initial state of StackPtr
Program variables
CP/M
HighMem
Figure A-7: Memory map during execution in direct mode
When a program is compiled, the end of the object code is known. The heap
pointer HeapPtr is set to this value by default, and the heap grows from here
and upwards in memory towards the recursion stack. The maximum memory
size is B DOS minus one (indicated on the compiler Options menu). Program
variables are stored from this address and downwards. The end of the vari-
ables is the 'top of free memory' which is the initial value of the CPU stack
pointer StackPtr. The CPU stack grows downwards from here towards the
position of the recursion stack pointer RecurPtr, $400 bytes lower than
StackPtr. The recursion stack grows from here downward towards the heap.
When a program file is executed (either by the Run command with the Com-
file mode on the compiler Options menu selected, by an eXecute command,
or directly from CP/M), the memory is mapped as follows:
0000
CP/M and run-time workspace
Pascal Library
Default program start address
Object code
Program variables
------- ------------------- Default end address
Loader
Maximum memory size
CP/M
HighMem
Figure A-8: Memory map during execution of a program file
This map resembles the previous, except for the absence of the TURBO inter-
face, editor, and compiler (and possible error messages) and of the source
text. The default program start address (shown on the compiler Options
menu) is the first free byte after the Pascal runtime library. This value may be
manipulated with the Start address command of the compiler Options menu,
e.g. to create space for absolute variables and/or external procedures bet-
ween the library and the code. The maximum memory size is BOOS minus
one, and the default value is determined by the BDOS location on the compu-
ter in use.
CP/M-80 169
A.16.1.4 Execution of A Program File
The heap is used to store dynamic variables, and is controlled with the stan-
dard procedures New, Mark, and Release. At the beginning of a program, the
heap pointer HeapPtr is set to the address of the bottom of free memory, i.e
the first free byte after the object code.
The CPU stack is used to store intermediate results during evaluation of ex-
pressions and to transfer parameters to procedures and functions. An active
for statement also uses the CPU stack, and occupies one word. At the begin-
ning of a program, the CPU stack pointer StackPtr is set to the address of the
top of free memory.
The recursion stack is used only by recursive procedures and functions, i.e.
procedures and functions compiled with the A compiler directive passive
(~A-}). On entry to a recursive subprogram it copies its workspace onto the
recursion stack, and on exit the entire workspace is restored to its original
state. The default initial value of RecurPtr at the beginning of a program, is 1 K
($400) bytes below the CPU stack pointer.
allow the programmer to control the position of the heap and the stacks.
The type of these variables is Integer. Notice that HeapPtr and RecurPtr may
be used in the same context as any other Integer variable, whereas StackPtr
may only be used in assignments and expressions.
When these variables are manipulated, always make sure that they point to
addresses within free memory, and that:
Needless to say, assignments to the heap and stack pointers must never oc-
cur once the stacks or the heap are in use.
Note that no checks are made at any time to insure that the CPU stack does
not overflow into the bottom of the recursion stack. For this to happen, a re-
cursive subroutine must call itself some 300-400 times, which must be con-
sidered a rare situation. If, however, a program requires such nesting, the fol-
lowing statement executed at the beginning of the program block will move
the recursion stack pointer downwards to create a larger CPU stack:
CP/M-80 171
A.16.2 The Heap and The Stacks
Notes:
This appendix describes features of TU RBO pascal specific to the various 16-
bit implementations. The appendix has three sub-sections:
The CP/M -86 implementation which deals with information specific to the
CP/M-86 implementation.
1) Things you must know to make efficient use of TURBO Pascal. These are
described in section B.1.1 .
2) The remaining sections describe things which are only of interest to expe-
rienced programmers, e.g. calling machine language routines, technical
aspects of the compiler, etc.
The only difference between the two implementations is that then command
Com-file is called Cmd-file in the CP/M-86 implementation.
The three commands M, C, and H select the compiler mode, i.e. where to put
the code which results from the compilation. Memory is the default mode.
When active, code is produced in memory and resides there ready to be acti-
vated by a Run command.
Com-file is selected by pressing C. The arrow moves to point to this line. The
compiler writes code to a file with the same name as the Work file (or Main
file, if specified) and the file type .COM (in CP/M-86 the file type is .CMD).
This file contains the program code and Pascal runtime library, and may be
activated by typing its name at the console.
When the Com or cH n mode is selected, four additional lines will appear on
the screen:
The O-command is used to set the minimum size of the code segment for a
.COM using Chain or Execute. As discussed in section B.1.9 , Chain and Exe-
cute do not change the base addresses of the code, data, and stack seg-
ments, and a 'root' program using Chain or Execute must therefore allocate
segments of sufficient size to accommodate the largest segments in any
Chained or Executed program.
Consequently, when compiling a 'root' program, you must set the value of the
Minimum Code Segment Size to at least the same value as the largest code
segment size of the programs to be chained/executed from that root. The re-
quired values are obtained from the status printout terminating any compila-
tion. The values are in hexadecimal and specify number of paragraphs, a para-
graph being 16 bytes.
The D-command is used to set the minimum size of the data segment for a
.COM using Chain or Execute. As discussed above, a 'root' program using
these commands must allocate segments of sufficient size to accommodate
the largest data of any Chained or Executed program.
Consequently, when compiling a 'root' program, you must set the value of the
Minimum Data Segment Size to at least the same value as the largest data
segment size of the programs to be chained/executed from that root. The re-
quired values are obtained from the status printout terminating any compila-
tion. The values are in hexadecimal and specify number of paragraphs, a para-
graph being 16 bytes.
This value specifies the minimum memory size required for stack and heap.
The value is in hexadecimal and specifies a number of paragraphs, a para-
graph being 16 bytes.
This value specifies the maximum memory size allocated for stack and heap.
It must be used in programs which operate in a multi-user environment like
Concurrent CP/M -86 to assure that the program does not allocate the entire
free memory. The value is in hexadecimal and specifies a number of para-
graphs, a paragraph being 16 bytes.
When you run a program compiled in memory, and a runtime error occurs, the
editor is invoked, and the error is automatically pointed out. This, of course, is
not possible if the program is in a .COM/.CMD file or an .CHN file. Run time
errors then print out the error code and the value of the program counter at
the time of the error, e.g.:
To find the place in the source text where the error occurred, enter the F com-
mand. When prompted for the address, enter the address given by the error
message:
Ent e r PC;---1OO.Q
The place in the source text is now found and pointed out exactly as if the er-
ror had occurred while running the program in memory.
The first constant specifies the segment base address, and the second cons-
tant specifies the offset within that segment. The standard identifiers CSeg
and OSeg may be used to place variables at absolute addresses within the
code segment (C5eg) or the data segment (05eg):
Absolute may also be used to declare a variable "on top" of another variab-
le, i.e. that a variable should start at the same address as another variable.
When absolute is followed by the variable (or parameter) identifier, the new
variable will start at the address of that variable (or parameter).
Example:
var
St r: string[ 32];
StrLen: Byte absolute Str;
This declaration specifies that the variable StrLen should start at the same ad-
dress as the variable Str, and as the first byte of a string variable contains the
length of the string, StrLen will contain the length of Str. Notice that an abso-
lute variable declaration may only specify one identifier.
Further details on space allocation for variables are found in section B.1.12 .
B.l.4.1 Addr
Syntax: Addr(Name)
Returns the address in memory of the first byte of the variable with the identi-
fier Name. If Name is an array, it may be subscribed, and if Name is a record,
specific fields may be selected. The value returned is a 32 bit pointer consist-
ing of a segment address and an offset.
B.l.4.2 afs
Syntax: Ofs(Name)
Returns the offset in the segment of memory occupied by the first byte of the
variable, procedure or function with the identifier Name. If Name is an array, it
may be subscribed, and if Name is a record, specific fields may be selected.
The value returned is an Integer.
8.1.4.3 Seg
Syntax: Seg(Name)
Returns the address of the segment containing the first byte of the variable,
procedure or function with the identifier Name. If Name is an array, it may be
subscribed, and if Name is a record, specific fields may be selected. The value
returned is an Integer.
8.1.4.4 Cseg
Syntax: Cseg
Returns the base address of the Code segment. The value returned is an Inte-
ger.
8.1.4.5 Dseg
Syntax: Dseg
Returns the base address of the Data segment. The value returned is an Inte-
ger.
8.1.4.6 Sseg
Syntax: Sseg
Returns the base address of the Stack segment. The value returned is an Inte-
ger.
TURBO Pascal offers four predefined arrays of type Byte, called Mem,
MemW, Port and PortW which are used to access CPU memory and data
ports.
The predefined arrays Mem and Mem Ware used to access memory. Each
component of the array Mem is a byte, and each component of the array
Wmem is a word (two bytes, LSB first). The index must be an address speci-
fied as the segment base address and an offset separated by a colon and both
of type Integer.
The following statement assigns the value of the byte located in segment
0000 at offset $0081 to the variable Value
places the value of the Integer variable Value in the memory location occu-
pied by the two first bytes of the variable Var.
The Port and Port W array are used to access the data ports of the 8086/88
CPU. Each element of the array represents a data port, with the index corre-
sponding to port numbers. As data ports are selected by 16-bit addresses the
index type is Integer. When a value is assigned to a component of Port or
Port W it is output to the port specified. When a component of port is referen-
ced in an expression, its value is input from the port specified. The compo-
nents of the Port array are of type Byte and the components of Port Ware of
type Integer.
Example:
Port[ 56] : = 10;
The use of the port array is restricted to assignment and reference in ex-
pressions only, i.e. components of Port and PortW cannot be used as variab-
le parameters to procedures and functions. Furthermore, operations referring
to the entire port array (reference without index) are not allowed.
The standard function Ptr can be used to assign specific values to a pointer
variable. The function returns a 32 bit pointer consisting of a segment address
and an offset.
Example:
POinter: =Pt r(Cseg, $80);
A pointer value is represented as a 32 bit entity and the standard function Ord
can therefore not be used to obtain its value. Instead the functions ors and
Seg must be used.
The following statement obtains the value of the pointer P {which is a seg-
ment address and an offset}:
SegmentPart : =Seg(p~ );
OffsetPart:=Ofs(P~);
The reserved word external is used to declare external procedures and func-
tions, typically procedures and functions written in machine code.
The type of the filename is .COM in the MS-DOS version and .CMD in the
CP/M-86 version. Only the code segment of a .CMD file is loaded.
Example:
procedure Di skReset; external 'DSKRFSEI";
funct ion IOstatus: boo lean; external 'IOSTAT';
Chain(Fi Ie)
Execute(File)
where File is a file variable of any type, previously assigned to a disk file with
the standard procedure Assign. If the file exists, it is loaded into memory and
executed.
The Chain procedure is used only to activate special TURBO Pascal .CHN fi-
les, i.e. files compiled with the cH n-file option selected on the Options menu
(see section B.1.1.1 ). Such a file contains only program code; no Pascal li-
brary, it uses the Pascal library already present in memory.
The Execute procedure works exactly as if the program had been activated
from the operating system (with the limitation that parameters can not be
passed from the command line).
Chaining and eXecuting TURBO programs does not alter the memory alloca-
tion state. The base addresses and sizes of the code, data and stack segments
are not changed. It is therefore imperative that the first program which exe-
cutes a Chain statement allocates enough memory for the code, data, and
stack segments to accommodate largest .CHN program. This is done by using
the Options menu to change the minimum code, data and free memory sizes
(see section B.1.1 ).
If the disk file does not exist, an I/O error occurs. This error is treated as de-
scribed in section 14.8. When the I compiler directive is passive ({$I-}), pro-
gram execution continues with the statement following the failed Chain or Ex-
ecute statement, and the IOresult function must be called prior to further I/O.
Data can be transferred from the current program to the chained program eit-
her by shared global variables or by absolute address variables.
Example:
Program MAIN. COM:
program Ma i n;
var
Txt: string[ 80] ;
CntPrg: file;
begin
Write('Enter any text: ,); ~adln(Txt);
As s i gn( CntPrg, , ChrCount . ehn' ) ;
Chain(CntPrg) ;
end.
Program CHRCQUNT.CHN:
program ChrCount;
var
Txt: string[ 80] ;
NoOfChar,
NoOfUpc,
I: Integer;
begin
NoOfUpc . - 0;
NoOfChar : = Length(Txt);
for I := 1 to length(Txt) do
i f Txt[ I] in [ 'A' .. 'Z'] then NoOfUpc . - Succ(NoOfUpc);
Write( 'No of characters in entry: ',NoOfChar);
Writeln( '. No of upper case characters: " NoOlUpc,'. ,);
end.
Note that neither Chain nor Execute can be used in direct mode, i.e. from a
program run with the compiler options switch in position Memory (section
B.1.1.1 ).
TURBO Pascal features the inline statements as a very convenient way of in-
serting machine code instructions directly into the program text. An inline sta-
tement consists of the reserved word inline followed by one or more con-
stants, variable identifiers, or location counter references, separated by slash-
es and enclosed in parentheses.
The constants may be either literal constants or constant identifiers, and they
must be of type Integer. Literals generate one byte of code if within the range
0 .. 255 ($OO .. $FF). otherwise two bytes in the standard byte reversed format.
Constant identifiers always generate two bytes of code.
A variable identifier generates two bytes of code (in byte reversed format)
containing the offset of the variable within its base segment. Global, local and
typed constants occupies different segments as follows:
Global variables resides in the data segment and the offset generated is re-
lative to the OS register.
Local variables reside in the stack segment and the offset generated is rela-
tive to the S P register.
Typed constants reside in the code segment and the offset generated is re-
lative to the CS register.
When an inline statement terminates, the registers SP, SP, DS, and SS must
be restored to their original values before the inline statement.
Inline statements may be freely mixed with other statements throughout the
statement part of a block, and inline statements may use all CPU registers.
Note, however, that the contents of the registers SP, SP, DS, and SS must
be the same on exit as on entry.
The TURBO Pascal run time package and the code generated by the compiler
are both fully interruptible. Interrupt service routines must preserve all regi-
sters used.
in1 ina ($50/ $53/ $51/ $52/ $57/ $56/ $06/ $FB);
An interrupt service procedure should not employ any I/O operations using
the standard procedures and functions of TURBO Pascal, as the BDOS is not
re-entrant. CP/M -86 users should note that B DOS calls should not be per-
formed from interrupt handlers, as these routines are not re-entrant. The pro-
grammer must initialize the interrupt vector used to activate the interrupt ser-
vice routine.
This procedure initializes the registers and flags as specified in the parameter
Result which must be of type:
Resul t = record
AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer;
end;
In the following descriptions, the symbol@ denotes the offset of the first byte
occupied by a variable of the given type within its segment. The segment base
address can be determined by using the standard function Seg.
Global and local variables, and typed constants occupy different segments as
follows:
Global variables reside in the data segment and the offset is relative to the
OS register.
Local variables reside in the stack segment and the offset is relative to the
BP register.
Typed constants reside in the code segment and the offset is relative to the
CS register.
The basic data types may be grouped into structures (arrays, records, and disk
files), but this structuring will not affect their internal formats.
8.1.12.1.1 Scalars
The following scalars are all stored in a single byte: Integer subranges with
both bounds in the range 0 .. 255, booleans, chars, and declared scalars with
less than 256 possible values. This byte contains the ordinal value of the va-
riable.
The following scalars are all stored in two bytes: Integers, Integer subranges
with one or both bounds not within the range 0 .. 255, and declared scalars
with more than 256 possible values. These bytes contain a 2's complement
16-bit value with the least significant byte stored first.
8.1.12.1.2 Reals
Reals occupy 6 bytes, giving a floating point value with a 40'-bit mantissa and
an 8-bit 2's exponent. The exponent is stored in the first byte and the man-
tissa in the next five bytes which the least significant byte first:
@ Exponent
@ +1 LSB of mantissa
@ +5 MSB of mantissa
The exponent uses binary format with an offset of$80. Hence, an exponent of
$84 indicates that the value of the mantissa is to be multiplied by 2 ~ ($84-
$80) = 2 ~ 4 = 16. If the exponent is zero, the floating point value is conside-
red to be zero.
The value of the mantissa is obtained by dividing the 40-bit unsigned integer
by Z' 40. The mantissa is always normalized, i.e. the most significant bit (bit 7
of the fifth byte) should be interpreted as a 1. The sign of the mantissa is sto-
red in this bit, however, a 1 indicating that the number is negative, and a 0 in-
dicating that the number is positive.
8.1.12.1.3 Strings
A string occupies as many bytes as its maximum length plus one. The first
byte contains the current length of the string. The following bytes contains
the string with the first character stored at the lowest address. In the table
shown below, L denotes the current length of the string, and Max denotes the
maximum length:
@ +L Last character
@ +L+1 Unused
@+Max Unused
8.1.12.1.4 Sets
An element in a Set occupies one bit, and as the maximum number of ele-
ments in a set is 256, a set variable will never occupy more than 32 bytes
(256/8).
If a set contains less than 256 elements, some of the bits are bound to be
zero at all times and need therefore not be stored. In terms of memory effi-
ciency, the best way to store a set variable of a given type would then be to
"cut off" all insignificant bits, and rotate the remaining bits so that the first
element of the set would occupy the first bit of the first byte. Such rotate ope-
rations, however, are quite slow, and TURBO therefore employs a compro-
mise: Only bytes which are statically zero (i.e. bytes of which no bits are used)
are not stored. This method of compression is very fast and in most cases as
memory efficient as the rotation method.
BitAddress = E mod 8
8.1.12.1.5 Pointers
8.1.12.2.1 Arrays
The components with the lowest index values are stored eft the lowest me-
mory address. A multi-dimensional array is stored with the rightmost dimen-
sion increasing first, e.g. given the array
Boardf1,81
Boardf2,11
Boardf2,21
Highest address:Boardf8,81
8.1.12.2.2 Records
The first field of a record is stored at the lowest memory address. If the record
contains no variant parts, the length is given by the sum of the lengths of the
individual fields. If a record contains a variant, the total number of bytes occu-
pied by the record is given by the length of the fixed part plus the length of
largest of its variant parts. Each variant starts at the same memory address.
Disk files are different from other data structures in that data is not stored in
internal memory but in a file on an external device. A disk file is controlled th-
rough a file interface block (FIB) as described in sections B.3.4 and B.2.4 . In
general there are two different types of disk files: random access files and text
files.
The basic components of a text file are characters, but a text file is further-
more divided into lines. Each line consists of any number of characters ended
by a CR/LF sequence (ASCII $00/ $OA). The file is terminated by a Ctrl-Z
(ASCII $1B).
8.1.12.3 Parameters
Parameters are transferred to procedures and functions via the stack which is
addressed through SS:SP.
On entry to an external subroutine, the top of the stack always contains the
return address within the code segment (a word). The parameters, if any, are
located below the return address, i.e. at higher addresses on the stack.
then the stack upon entry to Magic would have the following contents:
An external subroutine should save the Base Page register (BP) and then copy
the Stack Pointer SP into the Base Page register in order to be able to refer to
parameters. Furthermore the subroutine should reserve space on the stack for
local workarea. This can be obtained by the following instructions:
PUSH BP
MOV BP,SP
SUB SP, WORKARFA
The last instruction will have the effect of adding the following to the stack:
The following instruction will load length of the string into the AL register:
Before executing a RET instruction the subprogram must reset the Stack
Pointer and Base Page register to their original values. When executing the
RET the parameters may be removed by giving RET a parameter specifying
how many bytes to remove. The following instructions should therefore be
used when exiting from a subprogram:
MOV SP,BP
FQP BP
~ NoOfBytesTtiRemove
With a variable (var) parameter, two words are transferred on the stack giving
the base address and offset of the first byte occupied by the actual para-
meter.
With value parameters, the data transferred on the stack depends upon the
type of the parameter as described in the following sections.
B.1.12.3.2.1 Scalars
Integers, Booleans, Chars and declared scalars (Le. all scalars except Reals)
are transferred on the stack as a word. If the variable occupies only one byte
when it is stored, the most significant byte of the parameter is zero.
B.1.12.3.2.2 Reals
B.1.12.3.2.3 Strings
When a string is at the top of the stack, the topmost byte contains the length
of the string followed by the characters of the string.
A set always occupies 32 bytes on the stack (set compression only applies to
the loading and storing of sets).
B.1.12.3.2.5 Pointers
A pointer value is transferred on the stack as two words containing the base
address and offset of a dynamic variable. The value NIL corresponds to two
zero words.
Even when used as value parameters, Array and Record parameters are not
actually transferred on the stack. Instead, two words containing the base ad-
dress and offset of the first byte of the parameter are transferred. It is then the
responsibility of the subroutine to use this information to make a local copy of
the variable.
User written external functions must remove all parameters and the function
result from the stack when they return.
User written external functions must return their results exactly as specified
in the following:
Reals must be returned on the stack with the exponent at the lowest address.
This is done by not removing the function result variable when returning.
Sets must be returned on the top of the stack according to the format descri-
bed in section B.1.12.3.2.3. On exit SP must point at the byte containing the
string length.
During execution of TURBO Pascal program the following segments are allo-
cated for the progam:
a Code Segment,
a Data Segment, and
a Stack Segment
The heap is used to store dynamic variables, and is controlled with the stan-
dard procedures New, Mark, and Release. At the beginning of a program, the
heap pointer HeapPtr is set to low memory in the stack segment and the heap
grows upwards towards the stack. The pre-defined variable HeapPtr contains
the value of the heap pointer and allows the programmer to control the po-
sition of the heap.
The stack is used to store local variables, intermediate results during evalua-
tion of expressions and to transfer parameters to procedures and functions. At
the beginning of a program, the stack pointer is set to the address of the top
of the stack segment.
This section covers items peculiar to the MS-DOS and PC-DOS versions of
TURBO Pascal. For the sake of clarity and ease, these two operating systems
will simply be referred to as DOS in the following.
LongFilePos LongSeek
LongFileSize MsDos
For the purpose of making DOS system calls, TURBO Pascal introduces a
procedure MsDos, which has a record as parameter.
Details on DOS system calls and BIOS routines are found in the MS-DOS
Operating System Manual published by MicroSoft.
record
AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer;
end;
Before TURBO makes the DOS system call the registers AX, BX, CX, OX, BP,
SI, 01, OS, and ES are loaded with the values specified in the record para-
meter. When DOS has finished operation the MSdos procedure will restore
the registers to the record thus making any results from DOS available.
For some applications it is practical for a programmer to define his own input
and output drivers, i.e. routines which perform input and output of characters
to and from an external device. The following drivers are part of the TURBO
environment, and used by the standard I/O drivers (although they are not
available as standard procedures or functions):
The CanSt routine is called by the function KeyPressed, the Canln and Can-
Out routines are used by the CON:, TRM:, and KB D: devices, the LstOut rou-
tine is used by the LST: device, the AuxOut and Auxin routines are used by
the AUX: device, and the UsrOut and Usrln routines are used by the USR: de-
vice.
By default, these drivers are assigned to the DOS system calls as showed in
curly brackets in the above listing of drivers.
A user defined driver procedure or driver function must match the definitions
given above, i.e. a CanSt driver must be a boolean function, a Canln driver
must be a char function, etc.
Each file variable in a program has an associated file interface block (FIB). A
FIB occupies 176 bytes of memory and is for files of type text divided into two
sections: The control section (the first 48 bytes), and the sector buffer (the
last 128 bytes). The control section contains various information on the disk
file or device currently assigned to the file. The sector buffer is used to buffer
input and output from and to the disk file. Random access file variables and
untyped file variables does not have buffer section and therefore occupies
only 48 bytes.
@ Flags byte
@+1 File type
@+2 iCharacter buffer
@+3 Sector buffer pointer
@+4 Number of records (LSB)
The flags byte at@ contains two one-bit flags which indicate the current sta-
tus of the file:
The file type field at@ + 1 specifies the type of device currently assigned to the
file variable. The following values can occur:
When a file is assigned to a logical device, only the first three bytes of the FIB
are of significance.
The sector buffer pointer at @ +3 contains an offset from the first byte of the
sector buffer.
The 'number of records' field starting at@ +4 is a 32-bit number. All DOS file
I/O is performed through system functions 39 and 40 {random block read and
random block write), and the record length field in the FCB is always set to 1.
The sector buffer starting at @ +48 is included in file variables of type Text
only. Random access file variables and untyped file variables occupy only 48
bytes, and data is always transferred directly to or from the variable to be read
or written, leaving all blocking and deblocking to DOS.
A random access file consists of a sequence of records, all of the same length
and same internal format. To optimize file storage capacity, the records of a
file are totally contiguous.
TU RBO saves no information about the record length. The programmer must
therefore see to it that a random access file is accessed with the correct re-
cord length.
The size returned by the standard function Filesize is obtained form the DOS
directory.
The following three additional file routines exist to accommodate the ex-
tended range of records in DOS. These are:
LongFileSize function,
LongFilePosition function, and
LongSeek procedure
They correspond to their Integer equivalents FileSize, File Position, and Posi-
tion but operate with Rea Is . The functions thus return results of type Real, and
the second parameter of the LongSeek procedure must be an expression of
type Real.
The Flush procedure has no effect in DOS, as DOS file variables do not emp-
loy a sector buffer.
For the purpose of calling the CP/M-86 BDOS, TURBO Pascal introduces a
procedure Bdos, which has a record as parameter.
Details on BDOS and BIOS routines are found in the CP/M-86 Operating Sy-
stem Manual published by Digital Research.
record
AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer;
end;
Before TURBO calls the BDOS the registers AX, BX, CX, DX, BP, SI, DI, DS,
and ES are loaded with the values specified in the record parameter. When
the BDOS has finished operation the Bdos procedure will restore the regis-
ters to the record thus making any results from the B DOS available.
For some applications it is practical for a programmer to define his own input
and output drivers, i.e. routines which perform input and output of characters
to and from an external device. The following drivers are part of the TURBO
environment, and used by the standard I/O drivers (although they are not
available as standard procedures or functions):
The ConSt routine is called by the function KeyPressed, the Conln and Con-
Out routines are used by the CON:, TRM:, and KBD: devices, the LstOut rou-
tine is used by the LST: device, the AuxOut and AuxIn routines are used by
the AUX: device, and the UsrOut and Usrln routines are used by the USR: de-
vice.
A user defined driver procedure or driver function must match the definitions
given above, i.e. a ConSt driver must be a boolean function, a Conln driver
must be a char function, etc.
Each file variable in a program has an associated file interface block (FIB). A
FIB occupies 176 bytes of memory and is divided into two sections: The con-
trol section (the first 48 bytes), and the sector buffer (the last 128 bytes). The
control section contains various information on the disk file or device cur-
rently assigned to the file. The sector buffer is used to buffer input and output
from and to the disk file.
@ Flags byte
@ +1 File type
@+2 Character buffer
@+3 Sector buffer pointer
@+4 Number of records (LSB)
@+5 Number of records (MSB)
@+6 Record length in bytes (LSB)
@+7 Record length in bytes (MSB)
@+8 Current record number (LSB)
@+9 Current record number (MSB)
@ +10 Unused (reserved)
@ +11 Unused (reserved)
@ +12 First byte of CP/M FCB
The flags byte at@ contains four one bit flags which indicate the current sta-
tus of the file:
The file type field at@ + 1 specifies the type of device currently assigned to the
file variable. The following values can occur:
The sector buffer pointer at @ +3 contains an offset from the first byte of the
sector buffer. The following three fields are used only by random access files
(defined files) and untyped files. Each field consists of two bytes in byte rever-
sed format. Bytes@ + 10 and @ + 11 are currently unused, but reserved for fu-
ture expansion. Bytes@ +12 through@ +47 contain a CP/M file control block
(FCB). The last block of the FIB is the sector buffer used for buffering input
and output from and to disk files.
When a file is assigned to a logical device, only the first three bytes of the FIB
are of significance.
The FIB format described above applies to all defined files and textfiles. The
FIB of an untyped file has no sector buffer, as data is transferred directly bet-
ween a variable and the disk file. Thus, the length of the FIB of an untyped file
is only 48 bytes.
A random access file consists of a sequence of records, all of the same length
and same internal format. To optimize file storage capacity, the records of a
file are totally contiguous. The first four bytes of the first sector of a file con-
tains the number of records in the file and the length of each record in bytes.
The first record of the file is stored starting at the fourth byte.
This appendix lists all standard procedures and functions available in TURBO
Pascal and describes their syntax, thewir parameters, and their types. The fol-
lowing symbols are used to denote elements of various types:
Where parameter type specification is not present, it means that the pro-
cedure or function accepts variable parameters of any type.
procedure
Read (var F: file of type; var v: type);
Read (var F: text; var I: Integer);
Read (var F: text; var R: Real);
Read (var F: text; var C: Char);
Read (var F: text; var S:string);
Readln (var F: text);
Write (var F: file of type; var v: type);
Write (var F: text; I: Integer);
Write (var F: text; R: Real);
Write (var F: text; B: Boolean);
Write (var F: text; C: Char);
Write (var F: text; S:string);
Writeln (var F: text);
function
Abs (/: Integer): Integer;
Abs (R: Real): Real;
ArcTan (R: Real): Real;
Cos (R: Real): Real;
Exp (R: Real): Real;
Frac (R: Real): Real;
Int (R: Real): Real;
Ln (R: Real): Real;
Sin (R: Real): Real;
Sqr (/: Integer): Integer;
Sqr (R: Real): Real;
Sqrt (R: Real): Real;
function
Odd (/: Integer): Boolean;
Pred (X: scalar): scalar;
Succ (X: scalar): scalar;
function
Chr (I: Integer): Char;
Ord (X: scalar): Integer;
Round (R: Real): Integer;
Trunc (R: Real): Integer;
The Str procedure uses a non-standard syntax for its numeric parameter.
procedure
Delete (var S:string; Pos, Len: Integer);
Insert (S:string; var D: string; Pos: Integer);
Str (/: Integer; var S:string);
Str (R: Real; var S:string);
Val (S:string; var R: Real; var p: Integer);
Val (S:string; var/, P: Integer);
function
Concat (S1 ,S2, ... ,Sn: string): string;
Copy (S: string; Pos, Len: Integer): string;
Length (S:string): Integer;
Pas (Pattern, Source: string): Integer;
procedure
Assign (var F: file; name: string);
BlockRead (var F: file; var Dest: Type; Num: Integer);
BlockWrite (var F: file; var Dest: Type; Num: Integer);
Chain (var F: file);
Close (var F:file);
Erase (var F: file);
Execute (var F: file);
Rename (var F: file; Name: string);
Reset (var F:file);
Rewrite (var F:file);
Seek (var F: file of type; Pos: Integer);
function
Eof (var F:file): Boolean;
Eoln (var F: Text): Boolean;
FilePos (var F: file of type): Integer;
FilePos (var F: file): Integer;
FileSize (var F: file of type): Integer;
FileSize (var F: file): Integer;
Seek (var F: file; paS: Integer);
procedure
GetMem (var P: pointer; I: Integer);
Mark (var P:pointer);
New (var P:pointer);
Release (var P:pointer);
function
MemAvail : Integer;
Ord (P:pointer): Integer;
Ptr (/: Integer):pointer;
procedure
CrtExit;
Crtlnit;
ClrEol;
ClrScr;
DelLine;
GotoXY (X, Y: Integer);
InsLine;
LowVideo;
NormVideo;
procedure
Bdos (func,param: Integer);
Bios (func,param: Integer);
Delay (mS: Integer);
FiIIChar (var dest; length: Integer; data: Char);
FillChar (var dest; length: Integer; data: byte);
Halt;
Move (var source,dest; length: Integer);
Randomize;
function
Addr (var variable): Integer;
Addr (function identifier»): Integer;
Addr (procedure identifier»): Integer;
Bdos (Func, Param: Integer): Byte;
B dosH L (Func, Param: Integer): Integer;
Bios (Func, Param: Integer): byte;
B iosH L (Func, Param: Integer): Integer;
Hi (/: Integer): Integer;
IOresult : Boolean;
KeyPressed : Boolean;
La (/: Integer): Integer;
Random (Range: Integer): Integer;
Random: Real;
SizeOf (var variable): Integer;
SizeOf (type identifier»): Integer;
Swap (/: Integer): Integer;
UpCase (Ch: Char): Char;
Notes:
D. SUMMARY OF OPIERATORS
The following table summrizes all operators of TURBO Pascal. T.he operators
are grouped in order of decending precedence. Where Type of operand is in-
dicated as Integer, Real, the result is as follows:
Operands Result
Integer, Integer Integer
Real, Real Real
Real, Integer Real
The first operand of the in operator may be of any scalar type, and the second
operand must be a set of that type.
Examples:
{$I - }
{$I INCLUDE. FIL}
{$B-,R+,V-}
( *$X-*)
Notice that no spaces are allowed before or after the dollar-sign. A + sign af-
ter a directive indicates that the associated compiler feature is enabled (ac-
tive), and a minus sign indicates that is disabled (passive).
IMPORTANT NOTICE
All compiler directives have default values. These have been chosen
to optimize execution speed and minimize code size. This means that
e.g. code generation for recursive procedures (CP/M-80 only) and in-
dex checking has been disabled. Check below to make sure that your
programs include the required compiler directive settings!
Default: B+
Default: c+
Default: 1+
The I directive controls I/O error handling. When active, {$I+J, all I/O opera-
tions are checked for errors. When passive, {$I-J, it is the responsibility of the
programmer to check I/O errors through the standard function IOresult. See
section 14.8 for further details.
The I directive succeeded by a file name instructs the compiler to include the
file with the specified name in the compilation. Include files are discussed in
detail in chapter 1 7 .
The R directive controls run-time index checks. When active, {$R+}. all array
indexing operations are checked to be within the defined bounds, and all as-
signments to scalar and subrage variables are checked to be within range.
When passive, {$R-J. no checks are performed, and index errors may well
cause a program to go haywire. It is a good idea to activate this directive
while developing a program. Once debugged, execution will be speeded up by
setting it passive (the default state). For forther discussion, see sections 8.4
and 10.1 .
Default:V+
The W directive controls the level of nesting of With statements, i.e. the
number of records which may be 'opened' within one block. The W must
be immediately followed by a digit between 1 and 9. For further details,
please refer to section 11.2.
Default: K+
The K directive controls the generation of stack check code. When active,
t$K +}, a check is made to insure that space is available for local variables on
the stack before eack call to a subprogram. When passive, {$K-}, no checks
are made.
Notes:
The TURBO Pascal language closely follows the Standard Pascal defined by
Jensen & Wirth in their User Manual and Report, with only minor differen-
cies introduced for the sheer purpose of efficieny. These differencies are desc-
ribed in the following. Notice that the extensions offered by TURBO Pascal
are not discussed.
Dynamic variables and pointers use the standard procedures New, Mark, and
Release instead of the New and Dispose procedures suggested by Standard
Pascal. Primarily this deviation from the standard is far more efficient in terms
of execution speed and required support code, and secondly it offers compati-
bility with other popular Pascal compilers (e.g. UCSD Pascal).
The procedure New will not accept variant record specifications. This restric-
tion, however, is easily circumvented by using the standard procedure Get-
Mem.
F.2 Recursion
CP/M -80 version only: Because of the way local variables are handled dur-
ing recursion, a variable local to a subprogram must not be passed as a var-
parameter in recursive calls.
The standard procedures Get and Put are not implemented. Instead, the Read
and Write procedures have been extended to handle all I/O needs. The reason
for this is threefold: Firstly Read and Write gives much faster I/O, secondly
variable space overhead is reduced, as file buffer variables are not required,
and thirdly the Read and Write procedures are far more versatile and easier to
understand that Get and Put.
The standard procedure Page is not implemented, as the CP/M operating sy-
stem does not define a form-feed character.
The reserved word packed has no effect in TURBO Pascal, but it is still allo-
wed. This is because packing occurs automatically whenever possible. For the
same reason, standard procedures Pack and Unpack are not implemented.
The following is a listing of error messages you may get from the compiler.
When encountering an error, the compiler will always print the error number
on the screen. Explanatory texts will only be issued if you have included error
messages (answer V to the first question when you start TURBO).
Many error messages are totally self-explanatory, but some need a little ela-
boration as provided in the following.
01 ';' expected
02 ':' expected
03 ' " expected
04 '(' expected
05 ')' expected
06 ' =' expected
07 ': =' expected
08 '[' expected
09 ']' expected
10 ' .' expected
11 '.: expected
12 BEGIN expected
13 DO expected
. 14 END expected
15 0 F expected
17 TH EN expected
18 TO or DOWNTO expected
20 Boolean expression expected
21 File variable expected
22 I nteger constant expected
23 I nteger expression expected
24 Integer variable expected
25 Integer or real constant expected
26 I nteger o~ real expression expected
27 I nteger or real variable expected
28 Pointer variable expected
29 Record variable expected
30 Simple type expected
Simple types are all scalar types, except real.
31 Simple expression expected
32 String constant expected
Fatal errors at run-time result in a program halt and the display of the mes-
sage:
where NN is the run-time error number, and addr is the address in the pro-
gram code where the error occurred. The following contains explanations of
all run-time error numbers. Notice that the numbers are hexadecimal!
Notes:
o. % ERROR MESSAGES
where NN is the I/O error number, and addr is the address in the program
code where the error occurred.
If I/O error checking is passive (1$1-}), an I/O error will not cause the program
to halt. I nstead, all further I/O is suspended until the result of the I/O opera-
tion has been examined with the standard function 10result. If I/O is attemp-
ted before 10result is called after en error, a new error occurs, possibly hang-
ing the program.
The following contains explanations of all run-time error numbers. Notice that
the numbers are hexadecimal!
The compiler error messages are collected in the file TURBO. MSG. These
messages are in English but may easily be translated into any other language
as described in the following.
The first 24 lines of this file define a number of text constants for subsequent
inclusion in the error message lines: a technique which drastically reduces the
disk and memory requirements of the error messages. Each constant is identi-
fied by a control character, denoted by a ~ character in the following listing.
The value of each constant is anything that follows on the same line. All cha-
racters are significant. also leading and trailing blanks.
The remaining lines each contain one error message, starting with the error
number and immediately followed by the message text. The message text
may consist of any characters and may include previously defined constant
identifiers (control characters). Appendix G lists the resulting messages in full.
When you translate the error messages, the relation between constants and
error messages will probably be quite different from the English version listed
here. Start therefore with writing each error mesage in full, disregarding the
use of constants. You may use these error messages, but they will require ex-
cessive space. When all messages are translated, you should find as many
common denominators as possible. Then define these as constants at the top
of the file and include only the constant identifiers in subsequent message
texts. You may define as few or as many constants as you need, the restric-
tion being only the number of control characters.
As a good example of the use of constants, consider errors 25,26, and 27.
These are defined exclusively by constant identifiers, 15 in total, but would re-
quire 101 characters if written in clear text.
The TURBO editor may be used to edit the TURBOMSG.OVR file. Control
characters are entered with the Ctrl-P prefix, i.e. to enter a Ctrl-A ( ~ A) into
the file, hold down the (CONTROl) key and press first p, then A. Control cha-
racters appear dim on the screen (if it has any video attributes).
Notice that the TURBO editor deletes all trailing blanks. The original message
therefore does not use trailing blanks in any messages.
~ITextfi Ie
~U out of range
~V variable
~W overf low
~x expected
~y type
~ [ Inval id
~] pOinter
01'; '~x
02': '~x
03', '~x
04' ( '~x
05')'~X
06' =' ~X
07' : =' ~X
08' [ '~X
09'] '~X
10'. '~X
11' .. '~X
12BFXHN~X
13IX)~X
14END~X
150F~X
17THEN~X
18TO~O roWNTO~X
20Boolean~E~X
21 ~L~V~X
22~K~C~X
23~K~E~X
24~K~V~X
25~K~O~R~C~X
26~K~O~R~E~X
27~K~O~R~V~X
308 imple~Y~X
318imple~E~X
32~8~C~X
33~8~E~X
34~8~V~X
35~T~X
36Type~F~X
37Untyped~G~X
40~P label
41Unknown~F~O syntax error
42~P~]~Y in preceding~y
definitions
43Duplicate~F~O label
44Type mismatch
45~C~U
61~Ls and~]s~A~H
62St ructured~Vs~A~H
63~Ts~A~H
65Untyped~Gs~A~H
66I/O~A
68~L components~B~Gs
69~[~Odering of fields
70Set base~Y~U
71~[ GOTO
72Label not within current block
73~P FORWARD procedure(s)
74INLINE error
75~N use of ABSOUITE
90~L not found
91Unexpected end of source
97Too many nested WITH's
98Memory~W
99Compi ler~W
K. TURBO SYNTAX
The syntax of the TURBO Pascal language is presented here using the forma-
lism known as the Backus-Naur Form. The following symbols are meta-
symbols belonging to the BNF formalism, and not symbols of the TURBO
Pascal language: .
All other symbols are part of the language. Each syntactic construct is printed
in italics, e.g.: block and case -element. reserved words are printed in bold-
face, e.g.: array and for.
location-counter-reference ::
multiplying-operator :: = *
=.
letter-or-digit :: = letter I digit
I • sign constant
1/ I div I mod I and Ishl Ishr
parameter-group :: = identifier-list: type-identifier
pointer-type :: = ~ type-identifier
pointer-variable :: = variable
procedure-and-function-declaration-part :: =
{procedure -or-function -declaration }
=
procedure-declaration :: procedure-heading block;
procedure-heading :: = procedure identifier ; I procedure identifier
( formal-parameter-section
{ , formal-parameter-section } ) ;
procedure-or-function-declaration :: = procedure-declaration I
function -declaration
=
procedure-statement :: procedure-identifier Iprocedure-identifier
( actual-parameter { , actual-parameter} )
=
program-heading :: empty I program program-identifier
file -identifier-list
program :: = program-heading block.
program-identifier :: = identifier
record-constant :: = (record-constant-element
{ ; record-constant-element } )
=
record-constant-element :: field-identifier: structured-constant
=
record-section :: empty I field-identifier { , field-identifier} : type
record-type :: = record field-list end
record-variable :: = variable
record-variable-list :: = record-variable { , record-variable}
referenced-variable :: = pointer-variable ~
relational-operator :: = = I <> 1<= I> = I < I> I in
repeat-statement :: =repeat statement { ; statement} until expression
repetitive -statement :: = while -statement I repeat-statement I for-statement
=
result-type :: type-identifier
scalar-type :: = (identifier { , identifier} )
Notes:
L. ASCII TABLE
DED HEX CHAR DED HEX CHAR DED HEX CHAR DED HEX CHAR
0 00 ~@ NUL 32 20 SPC 64 40 @ 96 60
1 01 ~A SOH 33 21 ! 65 41 A 97 61 a
2 02 ~B STX 34 22
. 66 42 B 98 62 b
3 03 ~C EI'X 35 23 u 67 43 C 99 63 c
4 04 ~D EDT 36 24 $ 68 44 D 100 64 d
5 05 ~E mQ 37 25 % 69 45 E 101 65 e
6 06 ~F ACK 38 26 8e 70 46 F 102 66 f
7 07 ~G BEL 39 27 , 71 47 G 103 67 g
8 08 ~H BS 40 28 ( 72 48 H 104 68 h
9 09 ~ I HI' 41 29 ) 73 49 I 105 69 i
10 8A ~J LF 42 2A 74 4A J 106 6A j
11 0B ~K VT 43 2B
*
+ 75 4B K 107 6B k
12 C:XJ ~L FF 44 2C , 76 4C L 108 6C 1
13 0D ~M CR 45 2D - 77 4D M 109 6D m
14 0E ~N SO 46 2E 78 4E N 110 6E n
15 0F ~O SI 47 2F / 79 4F 0 III 6F 0
16 10 ~p DLE 48 30 0 80 50 P 112 70 P
17 11 ~Q 001 49 31 1 81 51 Q 113 71 q
18 12 ~R 002 50 32 2 82 52 R 114 72 r
19 13 ~S 003 51 33 3 83 53 S 115 73 s
20 14 ~T 004 52 34 4 84 54 T 116 74 t
21 15 ~U NAK 53 35 5 85 55 U 117 75 u
22 16 ~V 8YN 54 36 6 86 56 V 118 76 v
23 17 ~w ErE 55 37 7 87 57 W 119 77 w
24 18 ~X CAN 56 38 8 88 58 X 120 78 x
25 19 ~y :EM 57 39 9 89 59 Y 121 79 Y
26 lA ~z SUB 58 3A : 90 5A Z 122 7A z
27 IB ~[ ESC 59 3B ; 91 5B [ 123 7B {
28 lC ~\ FS 60 3C < 92 5C \ 124 7C I
29 ID ~] GS 61 3D = 93 5D ] 125 7D }
30 IE RS
~~
62 3E > 94 5E ~
126 7E -
31 IF - US~
63 3F ? 95 5F - 127 7F DEL
Notes:
M. HELP!! !
This appendix lists a number of the most commonly asked questions and their
answers.
0: Why do I get garbage on the screen when I start the TURBO editor.
A: You have not installed TURBO for your systel'!1.
HELP!!! 241
M HELP!!!
N. TEIRMINAL DNSTAlLATOON
Before you use TURBO Pascal, it must be installed to your particular termi-
nal, i.e. provided with information regarding control characters required for
certain functions. This installation is easily performed using the program
TlNST which is described in this chapter.
After having made a work-copy, please store your distribution diskette safely
away and work only on the copy.
Now start the installation by typing TlNST at your terminal. Select Screen in-
stallation from the main menu. Depending on your version of TURBO Pascal,
the installation proceeds as described in the following two sections.
If you use TURBO Pascal without installation, the default screen set-up will
be used. You may override this default by selecting another screen mode from
this menu:
Each time TURBO Pascal runs, the selected mode will be used, and you will
return to the default mode on exit.
If your terminal is mentioned, just enter the corresponding number, and the
installation is complete. Before installation is actually performed, you are
asked the question:
This allows you to modify one or more of the values being installed as descri-
bed in the following. If you do not want to modify the terminal definition, just
type N, and the installation completes by asking you the operating frequency
of your CPU (see last item in this appendix).
If your terminal is not on the menu, however, you must define the required
values yourself. The values can most probably be found in the manual sup-
plied with your terminal.
Enter the number corresponding to None of the above and answer the
questions one by one as they appear on the screen.
In the following, each command you may install is described in detail. Your
terminal may not support all the commands that can be installed. If so, just
pass the command not needed by typing RETURN in response to the prompt.
If Delete line, Insert line, or Erase to end of line is not installed, these func-
tions will be emulated in software, slowing screen performance somewhat.
either Press first the Esc key, then the =. The entry will be ecchoed with
appropriate labels, i.e. <ESC> =.
or Enter the decimal or hexadecimal values separated by spaces. H ex-
adecimal values must be preceded by a dollar-sign. Enter
e.g. 27 61 or $lB 61 or $lB $30 which are all equivalent.
The two methods cannot be mixed, i.e. once you have entered a non-numeric
character, the rest of that command must be defined in that mode, and vise
versa.
A hyphen entered as the very first character is used to delete a command, and
echoes the text Nothing.
Terminal type:
Enter the name of the terminal you are about to install. When you complete
TlNST, the values will be stored, and the terminal name will appear on the
initial list of terminals. If you later need to re-install TURBO Pascal to this ter-
minal, you can do that by choosing it from the list.
If you want to initialize your terminal when TURBO Pascal starts (e.g. to
download commands to programmable function keys), you answer V for yes
to this question. If not, just hit RETURN.
If you answer V, you may choose between entering the command directly or
defining a file name containing the command string. The latter is a good idea
if the initialization string is long, as e.g. a string to program a number of func-
tion keys would be.
Here, you may define a string to be sent to the terminal when TURBO Pascal
terminates. The description of the initialization command above applies here.
Some terminals need a command after the two numbers defining the
row- and column cursor address.
Column first?
Most terminals require the address on the format: first ROW, then CO-
LUMN. If this is the case on your terminal, answer N. If your terminal
wants COLUMN first, then ROW, then answerV.
Binary address?
Most terminals need the cursor address sent on binary form. If that is
true for your terminal, enter V. If your terminal expects the cursor ad-
dress as ASCII digits, enter N. If so, you are asked the supplementary
question:
2 or 3 ASCII digits?
Enter the number of digits in the cursor address for your termi-
nal.
Enter the command that will clear the entire contents of your screen, both fo-
reground and background, if applicable.
This is normally the case; if it is not so on your terminal, enter N, and define
the cursor HOME command.
Enter the command that deletes the entire line at the cursor position.
Enter the command that erases the line at the cursor position from the cursor
position through the right end of the line.
If your terminal supports different video intensities, then define the command
that initiates the dim video here. If this command is defined, the following
question is asked:
Enter the delay in milliseconds required after the functions specified. RETURN
means 0 (no delay).
If you have made any errors in the definitions, enter N. You will then return to
the terminal selection menu. The installation data you haver just entered will
be included in the installation data file and appear on the terminal selection
menu, but installation will not be performed.
o. SUBJECT ONDtEX
A 18
A Note on Control Characters, Backspace, i 07
21 Backup, 16
A-command, 175, 176 r.AK files, 1 6
A-compiler directive, 170 Basic Data Types, 157, 187
Abort command, 34 Basic Symbols, 37
Abs, 132, 206 BDOS,145
Absolute Address Functions, Bdos function, 153,209
178 Bdos procedure, 153,208
Absolute Code, 216 BdosHL function, 153,209
Absolute value, 132 BEFORE USE, 5
Absolute variables, 144, Begin block, 28
146,177 Bios function, 154,209
Adding operators, 51 , 53 Bios procedure, 154,208
Addr, 147, 178,209 BiosHL function, 154,209
Allocating Variables (New), Blanks, 39
116 Block, 121
Arccus tangent, 132 Block Commands, 28
ArcTan, 132, 206 Begin block, 28
Arithmetic functions, 132, Copy block, 29
206 Delete block, 29
Array component, 75 End block, 28
Array Constants, 90 H ide/display block, 29
Array Definition, 75 Mark single word, 28
Array of characters, 109 Move block, 29
Array Subscript Optimization, Read block from disk, 29
148 Write block to disk, 30
Arrays, 75, 161, 190 BlockRead, 112,207
Arrays and Records, 165, 193 B 10ckWrite, 112, 207
Assign, 94, 207 Boolean, 42
Assigning a value to a Brackets, 37
pointer, 181 Byte, 41
Assignment operator, 37
Assignment Statement, 55
Auto Indentation, 35
Auto tab on/off switch, 31
Ctrl-E,23 lI)
Ctrl-F,23 D-command, 17, 175
Ctrl-Q Ctrl-B, 25 Data conversion, 106
Ctrl-O Ctrl-C, 25 Data segment, 175
Ctrl-O Ctrl-D, 25 Data Structures, 161, 189
Ctrl-O Ctrl-E, 25 Data transfer between
Ctrl-O Ctrl-K, 25 programs, 1 50, 183
Ctrl-O Ctrl-P, 26 Declaration Part, 47
Ctrl-O Ctrl-R, 25 Declared scalar types, 41
Ctrl-O Ctrl-S, 25 Defining a Pointer Variable,
Ctrl-O Ctrl-X, 25 115
Ctrl-R,24 DEL, 107
Ctrl-S,23 Delay, 128,208
Ctrl-W,23 Delete, 33, 69, 207
Ctrl-X, 23, 107 Delete a command, 245
Ctrl-Z,24 Delete block, 29
Cursor Movement, 34 Delete character under cursor,
Cursor Movement Commands, 21 27
Character left, 23 Delete commands, 27
Character right, 23 Delete character under
Line down, 23 cursor, 27
Line up, 23 Delete left character, 27
Page down, 24 Delete line, 27
Page up, 24 Delete right word, 27
Scroll down, 24 Delete to end of line, 28
Scroll up, 23 Delimiters, 39
To beginning of block, 25 DelLine, 128, 208
To bottom of screen, 25 Deviations from standard
To end of block, 25 Pascal, 37, 47 48,58,
To end of file, 25 65,67,89,219
To last position, 26 Digits, 37
To left on line, 25 Direct memory access, 147,
To right on line, 25 179
To top offile, 25 Direct port access, 148, 180
To top of screen, 25 Directory Command, 17
Word left, 23 Discriminated unions, 83
Word right, 23 Disk change, 14
Disk Files, 162, 190
Disk-reset, 14
Dseg,179
Dynamic variables, 115, 219
f G
F-command, 145, 176 Get and Put, 219
False, 42 GetMem, 119,208
Field constants, 92 Goto Statement, 56,220
Field list, 79 GotoXY, 128,208
Fields, 79
File handling routines, 207
File identifier, 93 !HI
File Interface Blocks, 159, H-command, 143, 174
198,202 Halt procedure, 208
File name indicator in editor, Heap, 116,170, 175,194
19 Heap Control Procedures and
File names, 14 Functions, 208
File of Byte, 200 H eapPtr, 1 68, 170, 194
File parameters, 122 Hi,136
File pointer, 93 Hi function, 209
File Standard Functions, 97 Hide/display block, 29
File type, 92, 93 Highlighting, 13
File Type Definition, 93 Home position, 128
FilePos, 97, 113, 207
Files On The Distribution
Disk, 6 o
FileSize, 97, 113,207 1/0,106
FileSize I/O checking, 114
with text files, 101 I/O error handling, 114
FillChar, 129,208 I/O error messages, 227
Find, 31 I/O mode selection, 104
Find and replace, 32 I/O Procedures and Functions, 205
Find Runtime Error, 145, 176 I/O to textfiles, 106
Flush, 95, 200 IBM PC Display Selection, 243
Flush IBM PC Screen Installation, 8
with text files, 101 Identifiers, 43
For statement, 60 If statement, 57
Foreign languages, 229 In-line M'achine Code, 152,
Forward References, 138 184
Frac, 133, 206 Include compiler directive,
Fractional part, 133 15
Free memory, 175, 176 Indent indicator in editor,
Free Unions, 83 19
Function Calls, 196,201 Indentation, 31
Function Declaration, 130 in this manual, 4
Function Designators, 54 Initialized variables, 89
Function Results, 165, 194 Input without echo, 102, 104
Functions, 130
Input L
characters, 106 L-command,14 I
editing, 107 Label Declaration Part, 48
numeric values, 107 Labels, 56
strings, 107 Large programs, 141
Insert, 69, 207 Length, 72, 207
Insert and Delete Commands, Length of strings, 67
26 Letters, 37
Insert commands, 27 Limitations on sets, 85
I nsert indicator in editor, Line break, 31
19 Line down, 23
Insert line, 27 Line indicator in editor, 1 8
Insert mode on/off switch, 26 Line Restore, 35
InsLine, 128, 208 Line up, 23
Installation, 8 Ln, 133, 206
Installation of Editing Lo, 136, 209
Commands, 9 Local variables as
Int, 133,206 var-parameters, 219
Integer, 41,43 Location counter reference,
Integer overflow, 41 152,185
Integer part, 133 Logarithm, 133
Internal Data Formats, 157, Logged Drive Selection, 14
187 Logical Devices, 102
Interrupt Handling, 156, 186 LongFilePos, 200
Intersection, 85 LongFileSize,200
Intr, 186 LongSeek, 200
Introduction, 1 Lower case, 43
IOresult, 114, 209 LowVideo, 129, 208
K
KeyPressed, 136, 209
We've crafted some special tools to help you create the best
Pascal programs in the least amount of time. Designed to
compliment the power and speed of Turbo Pascal, these are
functioning modules created to save you from the "rewriting
the wheel" syndrome.
B + Trees on Disk
The fastest way to implement searches in records. Perfect
for databases, address books or any other applications where
you need to search through information for data. And on disk
means you won't be cluttering RAM. Source code included!!!
Quicksort on Disk
The fastest way to sort. Preferred by knowledgeable profes-
sionals. Available for you now with commented source code.
Turbo Toolbox ©
Available May, 1984