





Pascal Programming Tool-kit
Reference manual




Volume I
{Version 2.06, Abridged}











Copyright 1995, 1996, P. Renaud
All Rights reserved.












P. Renaud
G-1151 West Klein Street
Mount Morris, Michigan  48458-2359
prenaud@genesee.freenet.org
Licensing Agreement

License

        This Software (and source code) is the exclusive property of the author and is licensed for use to 
the purchaser, much like the way one person rents use of a tool or a house or any tangible item of 
property for use to another person. This Software is licensed on a per user basis.  The author authorizes 
you, the Registered License Holder, to make as many copies of said software as you wish, provided that 
all the copies remain in your sole possession and for your exclusive use only.
        There will be no set limit on the number of computers this software may be installed on, provided 
the Software is reserved for exclusively use by only the Registered License Holder.  Separate licenses 
are required for legal use by any other users.

Terms

        The Registered License agreement begins on the date of purchase and remains in force until ter
minated.  The agreement may be terminated at any time, merely by destroying all held copies of the 
licensed product.  The right to use the product will  also be terminate if you fail to comply with any of the 
terms or conditions of this agreement.
        The Licensed Product may not be assigned, subleased or otherwise transferred by the Regis
tered License holder to another party unless that party also agrees to accept and abide by the terms and 
conditions of this License agreement.  If you transfer the Licensed Product, all copies in your possession 
must either be transferred along with it or destroyed.  Special user support will terminated upon transfer.
        Programs written and compiled using this software library and that contain any portion of licensed 
code may be used, given away or sold without additional license or fees, provided all copies bear a notice 
of copyright.

Rights

        The author reserves all rights under copyright law in the use and distribution of the library.  No 
additional license, fees or royalties will be imposed on the sale of programs bearing parts or sections of 
this library so long as the program author is properly registered and the program using sections of this 
library bares a valid copyright notice.

Warranty

        Due to the changeable nature of the code in this library, no warranties are made, either written or 
implied about it's suitability or any piece of it for any particular task or purpose.  This disclaimer includes, 
but isn't limited to any implied warranties of merchantability and fitness for any particular purpose.
        Neither the author or otherwise involved in the creation, production or distribution of this software 
shall be liable for any damages, either indirect or incidental.  In addition, in no event shall the author be 
liable for damages exceeding the minimum suggested contribution price of said software or code.
        The author of said programs using the aforementioned code must bare sole responsibility for the 
performance of said program and holds the library's author unaccountable.
        Demonstration programs may not be distributed apart from the above library either in source or 
executable form under the above agreement.
        Some states do not allow the exclusion or limitation of incidental or consequential damages, so 
portions of the above limitation may not apply to you.  
        This agreement shall be governed by the laws of the State of Michigan and shall inure to the ben
efit of the author and any successors, administrators, heirs and assigns.  Any action or proceeding 
brought by either party against the other arising out of or related to this agreement must only be brought 
in a STATE or FEDERAL COURT of competent jurisdiction location in Genesee County, Michigan.  The 
parties hereby consent to in personam jurisdiction of said courts.

Table of Contents
(Places may very)

 Licensing Agreement                            Page 1
 Table of Contents                                      Page 4
 Introduction                                           Page 6
 Part I         The Library                             Page 10
 Chapter 1      The B_Tree unit                 Page 12
 Chapter 2      The Character unit                      Page 17
 Chapter 3      The Check unit                  Page 20
 Chapter 4      The Core unit                   Page 23
 Chapter 5      The Draw unit                   Page 31
 Chapter 6      The Drives unit                 Page 38
 Chapter 7      The Editor unit                 Page 41
 Chapter 8      The FileMem unit                Page 47
 Chapter 9      The FillCode unit                       Page 51
 Chapter 10     The Fraction unit                       Page 54
 Chapter 11     The Generate_FileName unit      Page 57
 Chapter 12     The Indicators unit                     Page 59
 Chapter 13     The JoyStick unit                       Page 63
 Chapter 14     The KeyBoard unit                       Page 66
 Chapter 15     The Lock unit                   Page 70
 Chapter 16     The Matrices unit                       Page 73
 Chapter 17     The Menu unit                   Page 77
 Chapter 18     The Multiple unit                       Page 83
 Chapter 19     The Music unit                  Page 92
 Chapter 20     The Over unit                   Page 95
 Chapter 21     The PageMaker unit              Page 97
 Chapter 22     The Pick unit                           Page 103
 Chapter 23     The Pointer unit                Page 105
 Chapter 24     The Screen unit                 Page 110
 Chapter 25     The Search unit                 Page 113
 Chapter 26     The String_Utilities unit               Page 116
 Chapter 27     The Structures unit                     Page 121
 Chapter 28     The Tables unit                 Page 128
 Chapter 29     The TextEdit unit                       Page 131
 Chapter 30     The TextExtra unit                      Page 146
 Chapter 31     The Time unit                   Page 149
 Chapter 32     The Timer unit                  Page 152
 Chapter 33     The Windows unit                Page 154
 Chapter 34     The Words unit                  Page 164
 Chapter 35     The other units                 Page 167
 Part IIBeta Section                    Page 169
 Chapter 36     Introduction                            Page 170
 Chapter 37     The ANSI_CRT unit                       Page 171
 Chapter 38     The Frames unit                 Page 174
 Chapter 39     The Look unit                   Page 178
 Chapter 40     The TextCorrect unit            Page 181
 Chapter 41     The WindExtra unit                      Page 186
 Glossary                                               Page 189
 Acknowledgements                                       Page 197

Introduction

        Welcome to the versatile world of the Pascal Programmers Took-Kit.  Yes, I know it's a 
mouthful, but you'll get used to it.  Pascal Programming Tool-kit (henceforth I'll call it 
PPTool-Kit) is a collection of individual units designed for use among the Borland Turbo Pascal 
(R) family of compilers.  
        It was crafted for hobbyist and professionals alike, providing object code modules that 
you may find useful in the development of your Pascal programming projects.
        PPTool-kit units are specially designed code libraries that are easily incorporated in your 
Turbo Pascal (R) Program.  By merely referencing the name of the library in your source code, 
the compiler can search for, compile the library and give your programs access to many of it's 
advanced routines.
        Some of the library units are interdependent on each other while others are not.  
PPTool-kit builds on the standard libraries provided with the compiler itself. And not only are 
they designed to be extremely flexible to use, they are easy to work with too.
        The main goal of PPTool-kit is that they are consistent.  They strive to achieve the best 
possible performance with the most efficient use of resources.   The code should run cleanly 
while not wasting an extraordinary amount of memory or processor time.
        And they're fast. You'll find that most of the units included are written to achieve good 
performance using the 8088 processor.  Give them a 80x86 or more advanced processor and 
watch them really take off.

The Compiler

        Through the years, Turbo Pascal (R) has evolved in a variety of flavors.  Released in 
series, each version was in many ways very different from that of it's predecessor.  Features were 
added here and new additions included there as the product was continuously improved.  And 
each new version boasted improvements rendering it's predecessors obsolete.
        Not every version, however, has been accepted by everybody as that much better than the 
last.  Don't believe me?  Well, it's true. I've seen companies happily humming along with an 
earlier version of Turbo Pascal (R) while the latest greatest version sat idly nearby on one of 
their shelves gathering dust.  Believe me, it true!
        And what good is a library if it none of it can be used with the earlier compilers?  Who 
wants to purchase a tool-kit only to discover they must upgrade their compiler just to use the 
darn thing?  I wouldn't!
        Therefore, I've taken the trouble to test each unit under one of the older versions of the 
compiler.  If possible, the unit has been modified to work with as early a version as possible.  
This may sound contrary to what most people do, but it makes sense to me.  If it can compile 
under an earlier version then it should compile under a later one.  The tested versions start with 
version 4.0 and go on from there.  Although I've used and like version 3, it's much different and 
more limited than the later versions.   The differences are so great that they don't even appear to 
be the same compiler.
        If a particular unit doesn't compile under a particular earlier version of Turbo Pascal (R), 
it will exclude that version in the heading range.  Also, to make use of some of the later features, 
some of the units will include their additional features only when compiled under a later version 
of the compiler.
        Some of the units include the overlay compiler directive if they are designed to support 
overlaying.  If you are using Turbo Pascal (R) version 4, simply disable this compiler directive 
to compile the unit. (Simply insert a space between the left curly bracket and the dollar sign.)  
Again, the individual units are internally marked with the version of the compiler under which 
they will successfully compile.
        I'm sorry, but not all these unit's can be used with the earlier compilers.  However, I've 
tried to make as many as compatible as I can, even if it did mean foregoing a couple of the better 
features to do so.  Note that none of the unit's, for this very reason, use the object oriented 
features of the later Pascal compilers.  I know some of you programmers out there might find 
this rather disappointing, but consider the case if the shoe was on the other foot.  If you were 
stuck using an earlier version of the compiler and you needed code to work with, wouldn't you 
be bitterly disappointed to purchase a library that you couldn't use?  I know I would be.
        All of the units are compilable under Turbo Pascal (R) version 6 while most  will compile 
with versions 5.0 and still others, version 4.0.  In general, a later compiler version will easily 
compile the code for a previous version with the exception of versions earlier than version 4.  In 
any case, since the code sticks as closely as it can to the standard Turbo Pascal, if you find you 
can't compile the unit with your version of the compiler, you should find it easy enough to alter 
so that you can.

System Requirements

        These units are compilable under Turbo Pascal (R) version 4.0 (or sometimes later)  
running under MS-DOS (R), PC-DOS (R), DR-DOS (R) or MDOS (R) on the 8088 or 80x86 
family of compatible microprocessors.
        A hard disk drive is recommended, but not necessary.  PPTool-kit units may be 
individually compiled on floppies and pulled together for your use.  A high density disk drive is 
recommended for floppy drive systems, but some of the smaller units may be compiled on low 
density drives. 
        The particular version of  the disk operating system (henceforth DOS) necessary is 
determined primarily upon the version of the Turbo Pascal (R) compiler you're using.  The 
resulting code is also determined in much the same manner.
        This chart will define the version necessary to operate the compiler.

Turbo Pascal* version 4.0 requires MS-DOS** or PC-DOS*** version 2.0+
Turbo Pascal* version 5.0 requires MS-DOS** or PC-DOS*** version 2.0+
Turbo Pascal* version 6.0 requires MS-DOS** or PC-DOS*** version 2.0+

        Alternately, you can compile some of these units under OS/2 version 2.1 or greater using 
Speed Pascal/2.  While still in the Beta testing stage, I'm taking the time to test and enhance 
certain units to compile under that compiler as well.  Speed Pascal/2 while not yet complete 
looks very promising and has been long awaited.

Conventions

        I'm going to assume that you, the user of this library, has a somewhat fairly general 
knowledge of Turbo Pascal (R) and it's workings. If not, I'll later recommend a very good book 
to get you started.  I guess, I'll also have to assume that the user has general knowledge of one of 
the many flavors of DOS.  Not an easy assumption, but a necessary one.
        I'm also going to have to assume that you have a general knowledge of programming 
concepts too.  Not that I can't describe them as I go along, but for the fact that this manual is 
already much too long to do so.  I would describe them, but then this manual already exceeds the 
four hundred pages that I've tried to keep it under.  This time around, I've divided the manual 
into two volumes to make it easier.  Those of  you who've used the tool-kit before will 
understand why.
        Let's see...  I've highlighted the topics to made them stand out, plus I also spaced them 
out where possible.  And the current subject matter or special material is separated by using 
italics  Also note that normal text is displayed in the Roman font while the declarations and their 
explanations are displayed in Helvetica.  And finally, you'll find that example code is always 
displayed in the Courier font.  

Programming

        Okay, welcome to the wonderful world of Pascal Programming.  What you are about to 
embark on is perhaps the greatest user control of the Personal Computer available.  Turbo Pascal 
(R) is more than just another computer language.  It is perhaps one of the most important 
developments in the history of programming!  Not only is Pascal easy to use, but it's structured 
and versatile as well.
        Okay, now that I have all the hype out of the way, let's get down to business.  This 
manual is created in such a way to provide you with the information you need at the time you 
need it. Please Forgive me if I get a little dry at times, but that's how most manuals are supposed 
to be.  Don't ask me why, but that's the way it is.   Also forgive me if, on the other hand, I seem 
to ramble on a little too much.  I hate dry manuals and I'm probably rebelling against such things.
        Anyway, as far as the use of this manual goes, it was designed to be either read through 
from beginning to end.  (Just kidding?)  Okay, it can be read a chapter at a time, depending on 
the features you wish to use.

Installation

        The PPTool-Kit library is provided to you in original Pascal source code modules only.  
No, It is not a fluke, and I'm not crazy.  At least I hope that I'm not.  Anyway, it's the way, I 
think, things should be done.
        Okay, you might think of me as a little untrusting, but then again, I found it difficult to 
accept anything at face value and I hope you're the same when it comes to shopping for 
something.
        If you're ever gone out buy a car, everyone knows; you better take a good long look at 
everything under the hood in front of that salesman, even if you know absolutely nothing about 
engines or cars or such.  That's just common sense and it works.  The same thing with toasters, 
lawn mowers or sofa beds, take a good look at everything before you decide, even if all the 
fancy inners just mesmerizes you or makes your eyes glaze over.
        And that's also the most irritating thing I know of when buying software too.  Yes, I 
know that when you buy a program you only get the machine code and the instruction manual, 
and that it's all for the sake of keeping trade secrets and such, and that's all well and good.
        However, remember that with a car, or any tangible item, you get to customize it.  With a 
car, you can replace the engine if you want to go that far, and do all sorts of cool stuff to it that 
enhance it's performance.  With programs and some of the available programming libraries, 
however, it doesn't seem to work that way.  You're stuck with what you get, for better or for 
worse.
        So, I've included everything you'll need to compile the code with your own compiler.  
Not only does this ensure that you're going to get what you've paid for, and that you're not stuck 
with a unit that works with only a particular version of the compiler, you also get that good long 
look at what's under the hood.  And you can customize it!
        I don't really expect you to understand everything you find there.  Then again, (and I 
really hate to admit this) sometime when I go back to look at it, even I don't understand what I 
was quite working toward at the time.  Everyone's always told me that I do things in strange and 
twisted ways.  But that's beside the point.  The point is, don't expect anything to be simple, 
because it just isn't.
        If you understand your compiler, then it's really easy to use the code.  Simply copy one 
of the Pascal files (anything with the .Pas file extension attached to the end) from one of the 
distribution disk into your source code directory and then rev up your compiler to compile it.  
All the source code files are stored as standard ANSI (text) files.
        For a quick hard disk installation, try using the included INSTALL.Exe file.  Just type 
Install at the command line or click on the install program icon if you're using OS/2 (R) or 
Windows (R).
        
Pascal

        Okay, Finally about learning Pascal.  If you're still reading this, I'm guessing that you're 
not entirely familiar with it.  In fact, you're probably wondering what on earth it is.  To put it 
simply, Pascal is a very structured and carefully organized programming language.  It's 
extremely easy to use, featuring keywords and operation commands that are spelled out.
        The language itself was developed in the early seventies by Niklaus Wirth at the 
University of Switzerland.  It was named in honor of the French mathematician Blaise Pascal of 
the seventeenth century.
        Although some people may not care for it, one of Pascal's greatest strengths is the fact 
that it contains very strict type checking.   Every variable used in the program must be defined 
prior to it's use and every assignment must be compatible with the variable.  (There are ways to 
override this, however for very special programming situations.)  Another advantage is the fact 
that code is arranged in blocks and there are mechanisms built in that eliminate the need for the 
infamous "GOTO" command. 
        If you'd like to learn how to program in Pascal, I recommend reading Pascal: An 
introduction to the art and Science of Programming by Walter J. Savitch.  It's not easy to find 
anymore, but I found it to be very good.  Don't even try to learn it through the programming 
manual.  Not only is it difficult, it's very incomplete.

Part I
The Library

Chapter 1

The B-Tree unit

Version 1.9

        The B-Tree unit is a system of routines that provide for long term storage of simple sin
gle key records.  The unit provides all the procedures and functions necessary for manage
ment of a simple B-Tree record structure in a disk file.
        This unit is designed to allow easy implementation of a permanent B-Tree file of Pascal 
records using basic Turbo Pascal (R) random access disk basic.  The B-Tree data structure 
was chosen because it provides fastest possible data access by single keys on a secondary 
mass storages unit.
        The B-Tree is automatically managed as records are added, therefore, no optimizing pro
cedures or routines are necessary.  And to ensure that the structure provides the tightest file 
management, when a record is deleted, the structure is automatically adjusted.

How does it work?

        First, the program must open a B-Tree file for use.  The system handles all the particu
lars, the program merely has to hand it the size of the record, the offset of the key and it's 
length.  If the file doesn't yet exist, the B-Tree system automatically configures and creates 
one.
        Next, records may be entered into the database as needed.  After the records are entered, 
the system's routines provide access to them for various operations.  Records can be ac
cessed, updated, inserted and deleted in any order. Provided, of course that records exist in 
the system before they are accessed, updated or deleted.
        The system handles deletions with as equal ease as insertions.  In addition, deleted 
records and portions of the disk are tracked automatically to ensure the tightest file manage
ment possible. 
        Closing the tree file saves the data for later.  It's very important that the tree file be saved 
before the program ends, or record loss can result.  Again, B-Tree files should always be 
closed properly by the B-Tree System.
        This unit relies on the DOS unit to handle special disk accessing.

Are there any limitations?

        There are very few limitations with B-Tree. B-Tree was originally designed and opti
mized to work well on a single floppy diskette system, so this unit is sure to provide outstand
ing performance on a system with a hard drive.
        B_Tree is very safe.  It was vigorously tested during development and can safely handle 
large amounts of data.  Note, it is extremely important to ensure that a B-Tree file is properly 
closed by the system before the program ends, either legitimately or otherwise, to ensure that 
the new data is saved to the file. 
        B-Tree has been thoroughly tested with disk compression systems and works exceptional
ly well through them.

How to use

        First, somewhere in the declaration part of your program or unit, you must tell the compil
er that you are going to use the B-Tree record management system.  This is the easiest step 
performed by using the Uses clause.  Simply insert it into the program or unit after the name 
declaration.  Example:

Uses
  BTree;

        Next, somewhere in your type or variable declaration section, you have to declare a 
record type to hold the data that you wish to store in the B-Tree record system.  At least one 
type of record will be declared, although if you're using the B-Tree record system for other 
records, you would naturally define more record types.  Example:

Type
  My_Data_Type = array[ 1 .. 10 ] of Char; {or whatever type you need.}

        Also in the variable declaration section you will have to declare a record for the B-Tree's 
data to go in.  Without this record, B-Tree would be at a lost to figure out where and what it 
was doing.  Be sure to leave this record alone and leave it all to B-Tree. B-Tree knows what 
to do with it.  Example:

Var
  The_Tree: Tree_Type;
   
        Then, somewhere later in your code section you would have to open the B-Tree file sys
tem for the particular record you are storing.  This is the very first thing you must do in order 
to do anything with the B-Tree system.  Example:

Begin
  ...
  Open_Tree_File( The_Tree,'filename',Record_Size,Key_Offset,Key_Size );
  ...

        Depending on where you needed to in the program you now can use the various other 
functions that B-Tree provide.  Examples:

... Insert_In_Tree( The_Tree, Data_Record )

... Find_In_Tree( The_Tree, Data_Record )

... Find_First_In_Tree( The_Tree, Data_Record )

... Find_In_Tree( The_Tree, Data_Record )

... Find_Next_In_Tree( The_Tree, Data_Record )

... Delete_From_Tree( The_Tree, Data_Record )

        Finally, you are at the end of the program.  Here the important step is to always close the 
B-Tree before the program ends.  If your program also ends somewhere else, be sure to pro
vide  a method of closing the tree files there as well.  Remember, always close your files be
fore the code ends, or else you may lose any data that was added during the course of your 
program's run.  Example:

  Close_Tree_File( The_Tree );
  ...
End.

        If you need a more complete example, look at the B-Tree demonstration program in the 
BtreDemo.Pas file.

Which compilers are supported?

        This unit has been designed and tested to compile under Turbo Pascal (R) versions 4.0 
through 6.0 and Speed Pascal/2 version Beta 4.  One procedure of this unit is not defined 
when compiled with version 4.0, the rest are.  Programs written with this unit will operate 
with DOS versions 2.0 through 7.0 and MDOS version 2.1 through 3.0 as well as OS/2 
versions 2.1 through 3.0.

Constants

Node_Maximum_Length - A constant that defines the maximum size of the B-Tree 
unit disk record in bytes.  This value can be enlarged for larger records or re
duced for better performance on floppy diskettes.

Maximum_Record_Size - A constant that defines the maximum size of the records 
allowed by B-Tree in bytes.  This value can be enlarged for larger records.

Maximum_Records_Per_Node - A constant that defines the maximum amount of 
records that are allowed per record node.  This value should not be changed un
less you're absolutely sure of what you are doing.

Minimum_Records_Per_Node - A constant that defines the minimum amount of 
records that are allowed per record node.  This value should not be changed un
less you're absolutely sure of what you're doing.

Types

The unspecified types are defined to allow the program to allocate a tree type.  They 
are automatically handled by the routines and should not be directly manipulated.

Tree_Type - This record type is the record that is allocated by your program for ex
clusive use by the B-Tree system.  Direct manipulation of the data in this record 
is strongly cautioned.

Procedures

Open_Tree_File - The procedure needed to open the file for storing the records and 
setting thing up.  If a file of the given name already exists, the information in it will 
be compared to ensure that the tree types are compatible.  The sizes and key 
offsets must match exactly of an error will result. The data structure is automati
cally set up for maximum efficiency.

Close_Tree_File - This procedure is used to close the file so that the data is saved 
in permanent storage.  Remember that if the file is not properly closed, the data 
in it may be lost.  Always remember to close the tree.

Functions

Insert_In_Tree -  (Insert data in the tree)  This function takes the given record and 
tries to insert the record into the tree structure.  It will return false if it fails.

Update_In_Tree - (Update data in the tree)   This function takes the record data in 
Old_Data and searches for the identical record in the tree.  Then it attempts to 
replace the old record with the new one.  If the process is successful, the func
tion returns true.

Delete_From_Tree - (Delete data from tree)  This function searches the tree for the 
exact record given in Old_Data.  If it's found, the record is removed from it.  This 
function returns true only if the operation was successful.
 
Find_In_Tree - (Find data in tree)  This function searches the tree for a record with 
the same key in the given record.  If it finds it, the given record data is replaced 
with the data from the tree record.  This function returns false if the key wasn't 
found in the tree.

Find_First_In_Tree - This function returns the very first record element in logical or
der of the tree.  It is very useful for producing an ordered list of records from the 
tree.  It returns false if the tree is empty.

Find_Next_In_Tree - This function returns the next record element in logical order of 
the tree.  It is very useful for producing an ordered list of records from the tree.  
This function returns false if there are no more elements.

Find_Last_In_Tree - This function will find the last record element in logical order of 
the tree.  It is very useful for ordered listings.  False is returned if the tree is 
empty.

Find_Previous_In_Tree -  This function will find the previous record element in the 
tree in logical order.  It is very useful for ordered listings.  This function returns 
false if there are no previous records in logical order.

Find_First_In_File -  This function will return the record first in the tree file, regard
less of logical or other orders.  No keys are needed and no order is guaranteed.  
This function returns false if the tree is empty.
 
Find_Next_In_File - This function will retrieve the next record of the tree file, regard
less of logical order.  No keys are needed except for the previous record and no 
order is guaranteed.  This function returns false if there isn't any more records.

Find_Last_In_File - This function will return the last record in the tree file, regardless 
of logical order.  No keys are necessary and no order is guaranteed. This func
tion returns false if the tree is empty.

Find_Previous_In_File - This function retrieves the previous element in the file.  It 
does not use any key except for the previously accessed one, so no order is 
guaranteed.  This function returns false if there isn't any record.

Change_Key_Routine - This procedure will change the default comparing routine for 
the given tree to the one supplied.  This is intended for advanced processing 
purposes only.  This procedure is not defined with Pascal version 4.0.

Chapter 2

The Character unit

Version 2.0

        The Character unit is a collection of routines designed for drawing various vector like 
characters on the screen device using the facilities of the Draw unit.  It's mostly a unit that 
helps fill out the Draw unit by adding the capability of text.  Note that all the standard ASCII 
characters are included as well as the extended characters introduced on the P.C.
        And each one is drawn on screen through a series of draw instructions to ensure that they 
all look crisp and sharp at most any size.

How does it work?

        Each character is drawn on the screen as a series of lines, curves and filled objects 
created on it's own individual scaled matrix of points.  The matrix is 22 by 22 points to 
ensure top quality drawing at any scale.  To ensure faster processing and a great amount of 
versatility, each character's procedure pointer is entered directly on a table of variable 
procedures.  In this manner, not only can a single character be changed, but all succeeding 
characters will remain unaffected.
        Please note that some of the character drawing routines do make use of others as starting 
or finishing points.  This ensures that a character class will remain consistent across the 
board.
        This unit relies on Turbo Pascal's (R) DOS unit through indirect means.  Also note that 
this unit relies completely on the PPToolKit's Draw and FillCode units as it's prime drawing 
methods.

Are there any limitations?

        As of right now, I can't recall any limitations with the source code except for the fact that 
there are no provisions for italicized characters or for rotating characters.  Perhaps I'll include 
provisions for these later on if enough interest is expressed about it.

How to use

        The Character unit is very easy to use, consisting of a very small number of direct user 
procedures.  In these next few examples, I'll try to give you a feel for the basics of the 
Character unit.  The first step, naturally, is to inform the compiler that your program intends 
to make use of the Character unit.  This is done through the compilers uses clause.  Here's an 
example...

        ...
        Uses
          Characters;
        ...

        See, wasn't that easy?  Now you merely have to draw the characters on the screen.  In 
this next example, that's exactly what we're going to do.

        ...
        Draw_Character( 1, 1, 20, 20, 'P' );
        ...

        See, that's it!  Now we have a "P" on the screen that's 20 pixels high and 20 pixels wide.  
This next example draws even more, fitting all the characters in the given box size.

        ...
        Draw_String( 1, 50, 100, 75, 'Only the best!'  );
        ...

        In that last example we drew characters 25 pixels high and fitted all the characters on a 
line only a hundred pixels long.  Sort of tight, but the Character unit can handle it.  Want to 
make something stand out?  Merely change the character color like this next example.

        ...
        Set_Character_Color( Red );
        Draw_String( 1, 1, 200, 100, 'Wow!' );
        ...

        That would certainly do it.  And that's about it for the Character unit.  Don't be afraid to 
try it out and see what she can do.  And if you feel up to the challenge, all the necessary 
routines are available for you to create and define your own type of character set.

Which compilers are supported?

        This unit has been designed and tested to compile under Turbo Pascal (R) versions 5.0 
through 6.0.   Although originally designed under version 4.0, as of the second version, the 
enhanced features had made it incompatible with the earlier version.

Types

Procedures_Array -  Defined for the sake of successor units, this is an array of 
procedures, each representing the appropriate character for it's code number.

Variables

Procedures -  Defined for the sake of successor units, this is a variable of the 
Procedures_Array type used to store the two hundred and fifty five procedure 
pointers needed to support all the possible characters.

Procedures

Set_Character_Color -  This procedure allows you to set the color used to draw the 
characters.  The Draw unit's color is not used for the Character unit.

Draw_Character -  This procedure draws a single character within the given screen 
box.

Draw_String -  This procedure draws a string of characters out designed to fit within 
the given screen box.

Initialize_Standard_Character -  This procedure redefines the character set to the 
default characters.  Additional character sets are supported via other character 
units.

Please note that all of the following Plot routines are defined for the sake of other character 
type units and are not for direct use by the user.

Plot_Lines -  This procedure plots a line within the character's matrix structure.

Plot_Arc -  This procedure plots an arc within the character's matrix structure.

Plot_Dot -  This procedure plots a dot within the character's matrix structure.

Plot_Circle -  This procedure plots a full circle within the character's matrix structure.

Plot_Filled_Line -  This procedure plots a filled line within the character's matrix 
structure for more complex drawings.

Plot_Filled_Arc -  This procedure plots a filled arc within the character's matrix 
structure for more complex drawings.

Plot_Filled_Ellipse -  This procedure plots a filled ellipse within the character's matrix 
structure for more complex drawings.

Chapter 3

The Check unit

Version 1.0

        Check was written as a simple debugging tool to aid in the finding and recovery of 
memory leaks.  Although not a very useful unit for a finished product, it oftentimes becomes 
invaluable to me during the testing and debugging part of program development.  I've decid
ed to include it in this library so that it can help you in your project development, just as it 
has helped me in mine. So, by now, I'm sure you're asking yourself, just what is a memory 
leak.
        Memory leaks are areas inside blocks of code where for some reason or other, memory is 
allocated or used and somehow doesn't get deallocated or returned back to the system.  It, in 
essence becomes lost.  Memory leaks usually occurs where code gets very complex and can 
easily pop up where you least expect them.  But don't despair!  With Check, you'll find it 
easy to localize the trouble and correct it.

How does it work?

        Memory leaks aren't always apparent when you're working on your new code, and many 
times, they don't effect the operation of the program or the system.  Sometimes they are so 
subtle you won't even notice them without the aid of a special unit like this.  I've found 
memory leaks in units that I had thought were corrected long ago!
         And memory leaks don't just occur in development programs or beta products.  There 
are a lot of very expensive commercial products that have been around for a very long time 
(We won't mention names) which lose memory just as effectively as the newest of them.  
Yes, I've found some.
        How do they affect performance?
        On a small scale, they are sometimes hardly noticeable.  However, as a program becomes 
increasingly complex, a memory leak can alter it's performance on a very large scale. The 
effects add up and sometimes do so exponentially.
        If a memory leak is discovered, the unit will display the amount of memory lost and halt 
the program.  Care should be taken to use these routines sparingly so that the problem can be 
be quickly found. 

Are there any limitations?

        First and foremost, this unit is designed to be used during development on the procedural 
level.  It works best during the development or testing of each individual procedure, instead 
of as the program as a whole.   I'm sure you won't wish to include Check in your finished 
version of your program, or at least I can't think of any reason you would.
        Second, if your routine intends to allocate a section of memory and keep it, then this unit 
will not work properly.  This unit merely monitors the differences in memory usage before 
and after the routine.  If on the other hand, you allocate memory for temporary use with the 
intention of releasing it and your code fails to do so, this unit is invaluable in finding that.  
        The placement of the routines is critical to the success of it's operation, so use care and 
caution.
 
How to use

        Use of Check is relatively easy.  First you decide where you wish to use it.  I found it of
ten the best policy to place the routines around the procedure or unit which I wish to test at 
the time.  Then test run your code and watch what happens.  Example:

Begin
  ...
  Mark_Memory;
  My_Test_Procedure;
  Memory_Gone;
  ...
End.

         Also take note that if your code happens to alter it's performance internally, you should 
take the time and effort necessary to test it for each circumstance possible.  Sometimes your 
code can operate correctly under normal circumstances, but it may fail to return the memory 
in the event of a error or alternate situation.
        Also note that the order the procedures are calls is of the upmost importance.  Failing to 
call Mark_Memory before calling Memory_Gone will produce an error situation.

Which Compilers are supported?

        This unit has been designed and tested to compile under Turbo Pascal (R) versions 4.0 to 
6.0.  In addition, it should be noted that each version of the compiler allocates memory in  a 
slightly different manner.  Read the memory allocation section of your manual to understand 
the way your compiler operates.  
        Check has been tested and found to compile properly under Speed Pascal/2 version Beta 
4.  It's effectiveness hasn't been properly tested as the compiler may be altered before the 
official release.  Also note that OS/2 being a multitasking operating system may effect the 
available memory in unpredictable ways.

Procedures 

Mark_Memory - This procedure account of the amount of memory the program has 
available at the time.  It sort of takes a snapshot of the memory usage.

Memory_Gone - This procedure examines the difference between the first snapshot 
taken by Mark_Memory and the amount of memory the program has available at 
the time.  If there is a discrepancy between the two amounts, this procedure will 
flag the situation out by the output file (usually the screen) and halt the program 
immediately.

Chapter 4

The Core unit

Version 2.22

        The Core unit is a collection of many low level routines that are intended to be use by the 
other, more advanced units.  Core is not meant to be used alone, but since it is necessary for 
the others units which depend on it, I thought it only fitting to include a description of it here 
with an explanation of it's capabilities.
        Core exists mostly due to the fact that during the course of the other unit's evolvement, 
particularly the windowing units and the menu units,  I found it necessary to separate por
tions of the units from each other.  The advantage of doing so was that the other units could 
access the same general procedures without having to depending on the the other units being 
needed in the same program.
        This approach worked wonderfully and I found it easy to link the units up to each other 
with out having to be directly referenced (Depends on the compiler version).  In this way, the 
Menu unit, or the Editor unit for that matter, can include the features of the Window unit or 
the Multiple unit, without necessarily having to have one or the other stuck in the program 
with it wasn't needed.
        In effect, you can use the Menu unit alone if you wished and yet, if you wanted to use 
Menu with Windows or Multiple, they would work together as easily as they would work 
apart.

How does it work?

        Several of the routines in core are unrelated to each other.  The rest are depended on cer
tain primary units to be called before them which set modes or initialize variables or other 
such functions.  
        This unit relies on Turbo Pascal's (R) CRT and DOS units to function.  Under Speed 
Pascal/2, it also requires the OS2Supp unit which is included in the library for DLL support 
to the standard libraries.

Are there any limitations?

        The core unit contains several routines with very limited error checking  code.  This was 
intended to ensure very speedy execution speed.  Care must be taken to ensure that other 
programs used with them (Especially memory resident routines) are well behaved.

How to use

        The core unit is not intended to be used alone, but if you wish to do so, just make sure to 
use Get_The_Mode before you use any of the screen routines and use Set_Window_Frame 
or Make_Frame before you use any of the frame drawing routines.

Which compilers are supported?

        This unit has been designed and tested to be completely compilable under Turbo Pascal 
(R) versions 4.0 to 6.0.  Version 4.0 of the compiler does not allow the units to link, but the 
units will still work separately.  Furthermore, this unit is definitely not recommended for 
overlaying.  This unit will also compile under Speed Pascal/2 version 1.5, but doesn't use 
direct memory addressing under OS/2.  Instead all the activities are passed to the operating 
system.

Constants

No_Frame - Used by Set_Window_Frame to specify that no frame is to be used.

Frame_1 - Used by Set_Window_Frame to specify a frame of single lines all around.

Frame_2 - Used by Set_Window_Frame to specify a frame with a double top line.

Frame_3 - Used by Set_Window_Frame to specify a frame with a double bottom 
line.

Frame_4 - Used by Set_Window_Frame to specify a frame with a double line on the 
top and on the bottom parts of the frame.

Frame_5 - Used by Set_Window_Frame to specify a frame with a double line on the 
right and on the left sides.

Frame_6 - Used by Set_Window_Frame to specify a frame with a single line on the 
bottom of the frame.

Frame_7 - Used by Set_Window_Frame to specify a frame with a single line on the 
top of the frame.

Frame_8 - Used by Set_Window_Frame to specify a frame with double lines all the 
way around.

Frame_9 - Same as Frame_1, except with block corners.

Frame_10 - Same as Frame_2, except with block corners.

Frame_11 - Same as Frame_3, except with block corners.

Frame_12 - Same as Frame_4, except with block corners.

Frame_13 - Same as Frame_5, except with block corners.

Frame_14 - Same as Frame_6, except with block corners.

Frame_15 - Same as Frame_7, except with block corners.

Frame_16 - Same as Frame_8, except with block corners.

Frame_17 - Used by Set_Window_Frame to specify a frame with single lines and 
single inward points all the way around.

Frame_18 - Used by Set_Window_Frame to specify a frame with double lines and 
double inward points on the top and bottom plus single lines with single inward 
points on the sides.

Frame_19 - Used by Set_Window_Frame to specify a frame with single lines and 
single inward points on the top on bottom plus double lines with double inward 
points on the sides.

Frame_20 - Used by Set_Window_Frame to specify a frame with double lines and 
double inward points all the way around.

Frame_21 - Used by Set_Window_Frame to specify a frame with double lines all the 
way around and double inward points on the top and bottom.

Frame_22 - Used by Set_Window_Frame to specify a frame with double lines all the 
way around and single inward points on the top and bottom.

Frame_23 - Used by Set_Window_Frame to specify a frame with double lines on the 
sides and a single line on the top and bottom with single inward points.

Frame_24 - Used by Set_Window_Frame to specify a frame with double lines on the 
top and bottom with double inward points and single lines on the sides.

Types

Frame_Type - Defines the structure used to hold the definition of a window for the 
window drawing procedures.

Storage_Record - Defines the structure used to hold the definition of a window for 
screen management.

Cell_Type - Defines the structure used to represent a single piece of screen informa
tion.  This data structure maps directly to the CRT text screen.

Area_Type - Defines a structure of cells used to directly access the screen informa
tion.

Area_Type_Pointer -  Defines a pointer to Area_Type.

Variables

Screen - A file that allows output for the descendent units directly to the CRT 
screen. Not yet supported properly under Speed Pascal/2.

The_Mode -  Set by Get_The_Mode, this variable allows the unit to keep track of the 
current mode the monitor screen is in.

Screen_Row_Limit - Set by Get_The_Mode, this variable holds the maximum 
amount of rows the current monitor mode allows.

Screen_Column_Limit - Set by Get_The_Mode, this variable holds the maximum 
amount of columns the current monitor mode allows.

Top_Of_Window - Set up by the Core unit itself, this variable is a pointer that points 
to part of the WinMin variable in the CRT.

Left_Of_Window - Also set up by the Core unit as a pointer to part of the WinMin 
variable in CRT.

Right_Of_Window - Also set up by the Core unit to point to part of WinMax of CRT.

Bottom_Of_Window - Set up by Core to point to part of WinMax of the CRT unit.

Up_Routine - This and the succeeding variable functions are set up for use by the 
descendent units for use by each other (Except with compiler version 4).  Defin
ing these variables in the Core unit established a method of indirect unit linking 
which increases the ease of use of several units together without making each 
use mandatory for the other.  This particular routine hands off window movement 
to other units.  Core sets these routines to originally point to functionless routines.

Down_Routine - Another function set up for use by a descendent unit of Core. 
Again, this particular routine is set up for granting a descendent unit the ability to 
move windows downwards if one of the descendent windowing unit is linked into 
the program.

Left_Routine - Yet another linking routine that grants descendent units the ability to 
move windows leftward if a windowing unit is linked into the program.

Right_Routine - Still another linking routine that grants descendent units the ability 
to move windows rightward if a windowing unit is linked into the program.

Expand_Width_Routine - A linking routine that grants descendent units the ability to 
expand windows if a windowing unit is linked into the program.

Expand_Height_Routine - A linking routine that grants descendent units the ability to 
expand windows if a windowing unit is linked into the program.

Reduce_Height_Routine - A linking routine that grants descendent units the ability to 
reduce windows if a windowing unit is linked into the program.

Reduce_Width_Routine - A linking routine that grants descendent units the ability to 
reduce windows if a windowing unit is linked into the program.

Lock_Routine - A linking routine that grants descendent units the ability to lock up 
the system if the Lock unit is linked into the program.

Procedures

Get_The_Mode - (Get the screen mode)  This procedure sets The_Mode to reflect 
the current video mode that the system claims to be using.  Depending on the 
mode, the video pointer is set to point to the beginning of the video buffer.  If the 
Screen mode is of a graphical nature, CRT's DirectVideo is set to false.

Put_Character_on_Screen - (Put character on monitor screen)  This procedure puts 
the given character on the monitor screen using the given attribute at the given 
location.  Either Move_Screen or the Basic Input/Output System (BIOS) is used 
depending on the current mode.

Write_Data - This procedure puts the given string of characters and attributes on the 
monitor screen at the given location using either Move_Screen or the BIOS.

Get_Character_From_Screen - (Get character from the monitor screen)  This proce
dure reads the character and attribute from the given location on the monitor 
screen.  It operates as an opposite of Put_Character_On_Screen.

Read_Data - This procedure reads a string of characters and attributes from the 
given location of the monitor screen.  It's opposite is Write_Data.

Change_Screen_Attribute - (Change attribute of text on screen)  This procedure 
changes the attribute of the characters defined by the given location and length 
to the new given attribute. 

Change_Window_Attribute - (Change attribute of text in screen window)  This proce
dure changes the attributes of the characters defined by the given location and 
length, relative to the current window on the screen to the new given attribute.

Dim_Screen_Attribute - (Dim attributes of text on screen)  This procedure dims the 
attributes of the characters on screen defined by the given location and length. 
The attributes are altered depending on the given attribute value.

Fill_Word - This procedure copies the word value from source to the given destina
tion, repeating as many times as defined by Length.  It operates like Turbo Pas
cal's (R) FillChar, but uses words instead.

Exchange - This procedure exchanges the data from source with the data in destina
tion using the CPU's built in exchanging command.  This is a faster method than 
using a temporary variable.

Deallocate_Storage - (Deallocate storage space)  This procedure takes the memory 
allocated by Allocate_Storage and returns it to the system.

Get_From_Storage - This procedure gets a characters and attribute, like 
Get_Character_From_Screen, from the given location in the simulated window.

Put_To_Storage - This procedure, like Put_Character_On_Screen, puts a character 
using the given attribute at the given location on the simulated screen.

Change_Storage_Attribute - This procedure works similar to that of 
Change_Screen_Attribute and allows the text attributes at the given location on 
the simulated screen to be altered.

Clear_Storage_Row - This procedure clears the given row of the simulate screen.

Clear_Storage_Column - This procedure clears the given column of the simulated 
screen.

Clear_Storage - This procedure clears the entire simulated screen of text.

Scroll_Storage_Down - This procedure scrolls the text in the simulated screen 
downwards.

Scroll_Storage_Up - This procedure scrolls the text in the simulated screen upwards.

Scroll_Storage_Right - This procedure scrolls the text in the simulated screen right
ward.

Scroll_Storage_Left - This procedure scrolls the text in the simulated screen leftward.

Scroll_Region_Up - This procedure scrolls the text in the given screen region up
wards.

Scroll_Region_Down - This procedure scrolls the text in the given screen region 
downwards.

Scroll_Region_Left - This procedure scrolls the text in the given screen region 
leftward.

Scroll_Region_Right - This procedure scrolls the text in the given screen region 
rightward.

Scroll_Window_Up - This procedure scrolls the text in the current Turbo Pascal (R) 
CRT unit window upwards.

Scroll_Window_Down - This procedure scrolls the text in the current CRT unit win
dow downwards.

Scroll_Window_Left - This procedure scrolls the text in the current CRT unit window 
leftward.

Scroll_Window_Right - This procedure scrolls the text in the current CRT unit win
dow rightward.

Set_Window_Frame - (Set the window frame)  This procedure sets the given frame 
style to one defined by the given values.

Define_Frame - (Define the user defined window frame) This procedure allows the 
programmer to set up a frame using his/her own characters.

Make_Frame - (Make window frame)  This procedure allows the programmer to 
generate other window frame by supplying specific data.

Draw_Window_Frame - This procedure draws a window frame on the screen using 
the given location parameters.

Blank_Row - This procedure clears a row of characters on the screen starting from 
the given left and proceeding along the given row until it meets the right limit.

Blank_Column - This procedure clears a column of characters on the screen starting 
at the given top and proceeding down along the given column until it hits the 
bottom limit.

Write_Error - This procedure looks at the given error code passed to it and halts the 
program and prints out the error code if the value is not zero.

Procedure_Default - This empty procedure is used to initialize the linking variable 
procedures. 

Functions

Reverse - This function switches the four high bits with the four low bits in the given 
byte.

Get_Screen_Address - (Get the memory address of the screen buffer)  This function 
returns a pointer to the memory address of the requested location in the screen 
buffer.

Allocate_Storage - (Allocate storage space for a simulated window)  This function 
obtains memory space to simulate a text window in memory.

Address_Storage - This function, like Get_Screen_Address, returns a memory ad
dress to the given simulate screen location.

Combine - This function alters a byte value allowing two attributes to be combined 
together so that the text color or background colors are easily manipulated.

Window_Width -  This function returns the current CRT screen width.

Chapter 5

The Draw unit

Version 1.0 

        The Draw unit, although new to this library, is a unit that I've been using for a seemingly 
very long time. Well, not as a whole combined unit, but as separate code pieces until I 
decided to try to fit them together in a orderly manner back in 91.  This is the result and I 
hope you like it.   This version has been simplified to work much better and be easier to use 
than it's predecessors.
        Now, I know what you're thinking.  Turbo Pascal (R) and most of the other compilers 
have built in graphic capabilities, (at least as an included unit), why would I have written this 
in the first place.  Well, you see it's  very simple.  I found out after having tried to do serious 
stuff with them, that I didn't like any of the graphic systems in Turbo Pascal (R) at all.  It was 
and still is far too rigid.  I needed something more flexible and this was it.
        The main difference between this and the other graphical routines is that this one can 
have it's graphical output redirected to any other type of  output device, or buffer storage 
mechanism for that matter.  And that you can play around with the rasper display buffer 
before the object is displayed.
        So, in a nutshell, the Draw unit is a very flexible and hopefully complete collection of 
graphical drawing routines.  

How does it work?

        The various routines within the unit calculate the pixel locations necessary for specific 
graphical structures and then send off the information either directly to the output routines or 
to the FillCode routine for storage until the object is completed.
        Each routine uses the fastest method I could find to perform the various tasks.  Since, 
naturally, I myself didn't know which methods were the best and fastest, I consulted several 
sources and compared them together.  Designing several procedures dealing with each 
method, and a few of my own, I placed them through heavy testing and only took the best 
performers for inclusion in this unit.
        Oh, and also, please note that I've included the sources for some of these methods later 
on in this chapter.  I'm sorry that they are incomplete as most of my copies predate my 
college years and are quite old.  
        This unit relies on Turbo Pascal's (R) DOS unit to provide a means for direct output to 
the system's graphical subsystem by the BIOS.  It also relies on the FillCode unit which is it's 
co-supporter for delayed graphical output.

Are there any limitations?

        For better or for worse, I tried to make my routines mimic the input methods of the Turbo 
Pascal (R) library.  The routines themselves may be altered if you wish to accept another 
form of input, and I wouldn't blame you if you did.  Just remember to ensure the changes 
should all be thoroughly tested and I can't support code that's been altered.
        Also note that somewhere during the development of this library, I happened to flip the 
coordinate system to perform more like the system operates.  I tried to ensure that all the 
code works this way, but please tell me if you find anything amiss.   
        The coordinate system for the PC works like this:  The X axis goes along the top of the 
screen increasing as it goes from left to right.  The Y axis going down the left side instead of 
going up in the opposite direction of the normal geometry.  Although I sort of regretting 
doing this, I figured it should come more naturally to others who are used to programming 
on the PC graphical system.

How to use

        Because of the complexity and sheer breath of this unit, and of course the amount of 
space available for this chapter, this section doesn't contain any examples beyond the 
rudimental.  for a more complete demonstration of the abilities of the Draw unit, please see 
the noted examples under the procedure listings.
        The Draw unit is a fairly easy unit to use.  It, however is very large and very versatile.  It 
features a broad array of drawing tools, both conventional and unconventional.   I really hope 
you find it useful and informative as well.
        To use the Draw unit, of course you must declare your intention to the compiler.  this is 
very easily done at the beginning of your program (or unit) via using the uses clause.  
Example:

        Uses
          Draw;

        Now, that was very simple, wasn't it?  Now all the power of the Draw unit is yours to 
command.  But note that you first must somehow get the system into a graphical mode for 
anything to appear on screen.  I've included the Screen unit for this, but Draw doesn't care 
what method you use.   Somehow, somewhere you must get your program into a graphical 
mode for the Draw unit to work.
        Also note that you should set up the aspect ratios yourself if you don't use the Screen unit.

        Uses
          Screen;

        In this next example, we'll assume that the computer is in some sort of graphical mode 
and that the Draw unit is ready and waiting.  We're going to draw a simple line on the screen.

        Begin
          ...
          Draw_Line( 1, 1, 100, 100 );
          ...

        Wasn't that easy.  This example code would draw a line from the top left corner of the 
screen all the way to somewhere in the center, depending on the screen graphical mode.  In 
this next example, we're going to draw a circle on the screen.

        ...
        Draw_Circle( 100, 100, 50 );
        ...

        That sure was easy, wasn't it?  We just drew a circle at the coordinates 100 by 100 with a 
radius of fifty pixels.  Well, more or less.  Note that the radius for a circle is always relative.  
That means that it isn't always the same in width as it is in height.  This makes up for the fact 
that some graphic modes have far more horizontal pixels than appropriate vertical pixels and 
if the circle was perfectly drawn in the rasper matrix, it would appear rather oblong on the 
screen.  The Draw unit tries to make up for this discrepancy.
        Heres another simple drawing, let's draw a box.

        ...
        Draw_Box(  100, 100, 150, 150, 60, True );
        ...

This last example drew a box on the screen and even drew a side and top.  This drawing 
routine is great for things such as bar graphs.  This last example is going to draw a solid 
object on the screen.  How about a nice solid box, with rounded corners.

        ....
        Draw_Filled_Rounded_Box( 40, 40, 100, 100, 10 );
        ...

        Now wasn't that easy?  A nice solid box was drawn on the screen with rounded corners 
to boot.  That's just a small sampling of the many routines available in the Draw unit.  Take 
her out for a test drive and really race the engine.

Which compilers are supported?  

        This unit has been designed and tested to compile under Turbo Pascal (R) versions 5.0 
through 6.0.  With a little work, it can even be altered to work with any other compiler even 
the 4.0 version.

References

Efficient Polygon-Filling Algorithms for Raster Display by Michael R. Dungaree, ACM 
Transactions on Graphics, Vol 2 No 4, October 1983.
Best Approximate Circles on Integer Grids by M. D. McLLroy, ACM Transactions on 
Graphics, Vol.2, No. 4, October 1983.
Curve-Drawing Algorithms for Rasper Displays by Jerry Van Aken and Mark Novak, 
Article source is unknown, but this is really a fantastic article if you can find it.

Constants

Y_Limit -  This value defines the current limit to the Y coordinate list.  This value 
changes to reflect the current video mode.

Types

Y_Range -  This type defines the maximum resolution allowed by the system for the 
height of the screen.  You many increase this range if necessary, but note that 
more heap space will be used up.

Variables

Drawing_Color -  This word defines the current drawing color used by the system.  
Feel free to alter this value whenever you like.

Filling_Color -  This word defines the current color used to fill the solid object.  You 
may change this color whenever you like.

Background_Color -  This word defines the color used to produce a blank screen.  
You may change this color whenever you wish to a new color, but it won't take 
effect until you clear the screen.

Procedures

Set_Pixel  -  This variable procedure is used throughout the system to transfer 
points from the algorithms to the screen.  You are encouraged to replace this 
procedure if you'd like to redirect the output to an alternate buffer.

Fill_Line -  This variable procedure is used throughout the system to transfer a 
horizontal line of points to the screen.  Again, you are encouraged to replace this 
procedure with one of your own to redirect the output.

Clear_Defaults -  This procedure puts the colors to their original values and moves 
the pointer to it's home position in the upper left hand corner.

Draw_Arc -  This procedure draws an arc on the screen at the given coordinates.

Draw_Box -  This procedure draws an x-y axis oriented rectangle on the screen with 
an optional depth extension.

Draw_Bezier_Spline -  This procedure draws a curvy line around and through the 
specified points.

Draw_Circle -  This procedure draws a circle on the screen at the given coordinates.

Draw_Elliptical_Arc -  This procedure draws a horizontally aligned elliptical arc on 
the screen at the given coordinates.

Draw_Ellipse -  This procedure draws a horizontally aligned ellipse on the screen at 
the specified location.

Draw_Filled_Circle -  This procedure draws a filled or solid circle at the given 
location on the screen.

Draw_Filled_Ellipse -  This procedure draws a filled or solid horizontally aligned 
ellipse on the screen.

Draw_Filled_Polygon -  This procedure draws a filled polygon on the screen in the 
same manner as the Turbo Pascal (R) graphical unit.  

Draw_Filled_Rectangle -  This procedure draws a filled or solid horizontally aligned 
rectangle on the screen at the specified location.

Draw_Filled_Rounded_Box -  This procedure draws a filled or solid horizontally 
aligned rounded rectangle on the screen at the supplied coordinates.

Draw_Line -  This procedure draws a line on the screen from one specified point to 
another.

Draw_Line_Relative -  This procedure draws a line on the screen from the current 
pointer to a relative location.

Draw_Line_To -   This procedure draws a line on the screen from the current pointer 
to an absolute location.

Draw_Pie_Slice -  This procedure draws a portion of a filled circle  on the screen in 
the shape of a pie portion.

Draw_Polygon -  This procedure draws a polygon on the screen in the same manner 
as the Turbo Pascal (R) graphic unit

Draw_Rectangle -  This procedure draws a horizontally aligned rectangle on the 
screen at the location provided.

Draw_Rounded_Box -  This procedure draws the outline of a rounded rectangle on 
the screen at the given location.

Draw_Sector -  This procedure draws a segment of a filled horizontally aligned 
elliptical arc at the given location.

Get_Aspect_Ratio -  This procedure returns the currently defined X and Y aspect 
ratios.

Set_Aspect_Ratio -  This procedure sets the X and Y aspect ratios to the supplied 
values.

Move_Relative -  This procedure moves the current pointer to a new location relative 
to it's old one.  Nothing is drawn on screen.

Move_To -  This procedure moves the current pointer to a new location by absolute 
coordinates.  Nothing is drawn on the screen.

Set_Background_Color -  This procedure is the more preferred way to alter the 
system's current background color.  

Set_Filling_Color -  This procedure is the more preferred way to alter the system's 
current filling color.

Set_Color -  This procedure is the preferred way to alter the system's current 
drawing color.

Roll_Point -  This procedure rolls a given point around the X, Y axis by the given 
amount.

Draw_Disjoint_Ellipse -  This procedure draws separate segments of a single 
horizontally oriented ellipse in a disjointed manner.

Draw_Ellipse_Box -  This procedure draws the outline of a horizontally oriented box 
on the screen with rounded corners at the given location.

Draw_Filled_Ellipse_Box -  This procedure draws a solid horizontally oriented box 
on the screen with rounded corners at the given location.

Draw_Elliptical_Arc_Job -  This procedure plots a horizontally aligned elliptical arc in 
the screen buffer.

Draw_Filled_Ellipse_Job -  This procedure plots a horizontally aligned ellipse on the 
screen buffer.

Functions

Get_Pixel -  This variable function reads the value of a particular pixel on the screen. 
 You are encouraged to replace this procedure with one of your own if you intend 
to redirect the output.

Chapter 6

The Drives unit

Version 1.1

        Drives is a unit containing a variety of drive accessing routines not available through the 
Turbo Pascal (R) DOS unit.  Perhaps they were overlooked or simply deemed unnecessary.  I 
however, missed not having access to these operating systems functions and so I wrote this 
little unit to help me.
        Recently, I revamped it (Read completely tested and debugged it) and decided to include 
it in this library with it's brothers.  Feel free to take a look at it and use it if you need to.  
Basically, it's a front end to the drive functions available through the disk operating system.

How does it work?

        In most cases, Drives obtains it's information by directly accessing the operating system. 
(DOS)  In a few cases, it was better to access the basic input/output system (BIOS or ROM 
subsystem) to obtain the information because the operating system (DOS) does  have the 
tendency to hide some of the finer details about the system.  The Speed Pascal/2 version gets 
most of it's information through the DOS unit, but in a indirect method, of course since I 
haven't yet learned how to do system calls.
        Drives relies directly on the Turbo Pascal (R) DOS unit for access to the operating 
systems interrupts.  Although it would be faster and easier to access them directly, I felt it 
would be a little safer to use the DOS routines for possible changes in the future 
implementations of the operating system or compiler.  

Are there any limitations?

        There isn't much error checking code for some of the routine.  This was designed to 
hasten the program execution time at the expense of forcing the programmer to be a little 
more careful with the input. 

How to use.

        Using the Drives unit is incredibly simple.  First you have to inform the compiler that 
your program intends to use the unit.  This is accomplished by the Pascal uses clause.  
Example:

Uses
  Drives;

        Next, you simple use the appropriate functions or procedures wherever you need them in 
your code.  Here's an example for inquiring which drives are available on the system. 

Var
  Drives: Drive_Set_Type;
...
Begin
  ...
  Check_System_Drives( Drives );
  ...
End.

        In this example, Drives now contains the set of valid drives (real or virtual) that are 
available to your program.  For more information, see each routines description in the 
reference section.

Which compilers are supported?

        Drives has been tested and verified to be completely compilable under Turbo Pascal (R) 
versions 4.0 through 6.0.  It's currently only partially compilable under Speed Pascal/2 Beta 
4.  Frankly, when asked why I don't test it for Turbo Pascal version 7.0, the reason, is I 
decided against purchasing it.  Silly of me to decide to wait until Borland came out with a 
version that would compiler programs for OS/2, it never happened.  Incidentally, I found 
Microsoft Window's programming to be a major nightmare and never did master the art of 
preventing it from crashing every thirty minutes.  For OS/2, check out SpeedSoft's new 
Speed Pascal/2!

Types

Drive_Set_Type - A set of characters from A to Z which turns out to be the most 
efficient and natural way to return the information about available drives.
 
Procedures

Check_System_Drives - This procedure returns in a set, all the available drives on 
the system regardless of whether they are available for use or not. (Mounted or 
unmounted)

Set_Current_Drive -  This procedure sets the default system drive to the one of the 
given character value.

Call_DOS_About_Drive -  This procedure inquires of the operating system about the 
existence of a particular drive.  It returns true if it does exist, otherwise it returns 
false.

Functions

Disk_Fixed -  This function returns true if the specified drive is permanently 
mounted, otherwise it returns false.  (Not yet complete under Speed Pascal/2)

Get_Current_Drive -  This function returns the current system drive as a character.

Does_This_Drive_Exist -  This function returns true if the given drives does exist, 
otherwise it returns false.

Drive_Number -  (Convert drive to number)  This function converts a drive letter to a 
drive number.

Chapter 7

The Editor unit

Version 3.3     

        Editor is a unit designed to provide simple editing routines for inputting and editing 
single pieces of data.  The editor unit provides several procedures useful for altering 
information in several types of simple data structures.  Routines are included for strings, 
integers of all sizes and Real numbers.
         Editor doesn't allow multiple lines of text like a word processor or file editor, but it does 
provide some of the standard WordStar (R)-like keystroke combinations to make editing 
tasks both comfortable and more familiar. And finally, Editor works well enough alone or in 
the company of some of the other units like Multiple or PPTool-Kit Windows (but not both 
together).

How does it work?

        The various routines of Editor allow variables to be passed through their appropriate 
procedures to the user so that he or she can input new values or alter the values already there.
        Editor implements inputting routines that poll the keyboard until the user enters  
appropriate keystrokes.  Depending on the keystroke received, Editor performs either an 
operation on the data, or alters the text itself, or if the keystroke isn't supported, Editor 
ignores it.  There are common keystrokes that each routine is able to recognize.  Among 
these are...

Escape - This key overrides the edits and exits the routine, rejecting all the alterations.
Ctrl-S, Left arrow - These keys moves the cursor to the left if possible.
Ctrl-D, Right arrow - These keys moves the cursor to the right if possible.
Ctrl-E, Up arrow - These keys normally exits the routine, accepting the alterations.
Ctrl-X, Down arrow - These keys normally exits the routine, accepting the alterations.
Ctrl-A, Ctrl-Left arrow - These keys move the cursor to the beginning of the left word.
Ctrl-F, Ctrl-Right arrow - These keys move the cursor to the beginning of the right word.
Ctrl-QS, Home - These keys move the cursor to the beginning of the line.
Ctrl-QD, End - These keys move the cursor to the ending of the line.
Tab, Ctrl-I - These keys move the cursor over to the next right tab stop.
Shift-Tab - This key moves the cursor over to the next left tab stop.
Insert, Ctrl-V - These keys toggle the insert mode.
Delete, Ctrl-G - These keys delete the character under the cursor.
Backspace, Ctrl-H - These keys delete the character to the left of the cursor.
Ctrl-Y - This key deletes the entire line.
Ctrl-QY - This key deletes all the data to the right of the cursor.
Ctrl-T - This key deletes the word to the right.
Ctrl-JL - This key restores the text on the line to it's original value.

        Editor relies directly on the CRT unit.  Furthermore, it references the Core, KeyBoard 
and String_Utilities units of the PPToolKit library.  Depending on the compiler version, this 
unit may link automatically with the Window unit or the Multiple unit and fully supports 
window movement keys.  This unit also links up with the Lock unit and supports system 
locking.

Are there any limitations?

        Each routine has it's own limitations, but the most prevalent is the lack of ability to check 
for extra errors during data entry.  Most of the error checking is performed after the data is 
entered and is in the process of being converted into a numerical form. 

How to use.

        Generally, each procedure must have been initialized before it is passed to the Editor 
routine, or it will consist of nothing but junk to begin with.  After that, the program must 
merely pass control of the variable to the routine, usually, but not necessarily proceeded by a 
prompt.  Here's a typical example which allows the user to alter the text presented on the 
third row in the first column...

Begin
  ...
  Data := 1/3;
  Set_Real( 3, 1, Data );
  ...
End.
        This example sets the variable to one third before it calls the setting routine.  The value is 
passed to the setting routine where the user is given the opportunity to alter the value.  The 
setting routine ends when the user relinquishes control by pressing an arrow, enter or escape.

Which compilers are supported?

        Editor has tested to be completely compilable under Turbo Pascal (R) versions 4.0 
through 6.0 and with Speed Pascal/2 version 1.5.  As necessary, some of the features such as 
the window movement keys and the user supplied help screens are not supported with Turbo 
Pascal compiler version 4.

Constants

Tab_Amount - This value determines the amount of spaces the tab key will move 
the cursor when it's pressed.  The default amount is eight.

Insert_Mode - This switch defines the mode which the editor is working in.  The 
entry mode is easily toggled back and forth by pressing the Insert key.  The 
default mode is overwrite mode in which new characters overwrite the old ones, 
but the user is free to switch this if desired.

Insert_Tab - This switch defines the way the tab key can work.  If it's true, the tab 
key is allowed to insert characters in insert mode, otherwise it merely moves the 
cursor.

Insert_At_EOLn - When set to true, this switch allows the current string to increase 
in size when extra characters are added.  Otherwise, the size of the line is set to 
remain constant.  The default is true.

Exit_On_Tab - When set to true, this switch allows the tab key to act just like the 
return key.  The default is false.

Move_Windows - When set to true, this switch allows the user the ability to move 
the top window when the Windows or Multiple unit is being used by the program.  
The default is true.

Lock_System - When set to true, this switch allows the user the ability to call up the 
system locking routine if the Lock unit is used by the program.  The default value 
is true.

Up_Key - This value is returned in Command if the up key was pressed to terminate 
the routine.

Down_Key - This value is returned in Command if the down key was pressed to 
terminate the routine.

Enter_Key - This value is returned in Command if the enter key was pressed to 
terminate the routine.

Escape_Key - This value is returned in Command if the escape key was pressed to 
terminate the routine.

Variables

Command - This byte size integer hold the last command value that was received by 
the Editor routine before it terminated.  This variable is supplied to make it easy 
for the program to peek at the value that ended the routine and decide what 
action to take.

Character - This character holds the last character that was received by the Editor 
routine before it terminated.  This variable is also supplied to make it easy for the 
program to look at the value and decide what action to take.

Help_Screen - This is a variable procedure (not defined with compiler version 4) that 
is called internally whenever the help (F1) key is pressed.  It's available for 
replacement by the program to provide context sensitive help.

Procedures

Edit_Byte - A procedure which allows the user to alter the byte size integer value 
passed to it as if it were a string.

Edit_Word - A procedure which allows the user to alter the word size integer value 
passed to it as if it were a string.

Edit_Short_Integer - A procedure which allows the user to alter the short size integer 
value passed to it as if it were a string.

Edit_Integer - A procedure which allows the user to alter the medium size integer 
value passed to it as if it were a string.

Edit_Long_Integer - A procedure which allows the user to alter the long size integer 
value passed to it as if it were a string. 

Edit_Real - A procedure which allows the user to alter the real number value passed 
to it as if it were a string.

Edit_String - A procedure which allows the user to alter the string passed to it.

Toggle_Byte - A procedure which allows the user the ability to alter the byte sized 
integer passed to it by using the arrow keys to increase or decrease it's value.

Toggle_Word - A procedure which allows the user the ability to alter the word sized 
integer passed to it by using the arrow keys to increase or decrease it's value.

Toggle_Short_Integer - A procedure which allows the user the ability to alter the 
short size integer passed to it by using the arrow keys to increase or decrease 
it's value.

Toggle_Integer - A procedure which allows the user the ability to alter the medium 
size integer passed to it by using the arrow keys to increase or decrease it's 
value.

Toggle_Long_Integer - A procedure which allows the user the ability to alter the long 
size integer passed to it by using the arrow keys to increase or decrease it's 
value.

Set_Byte - A procedure which allows the user the ability to alter the byte size integer 
passed to it by using a unique combination of movement, number keys and spin 
keys.
 
Set_Word - A procedure which allows the user the ability to alter the word size 
integer passed to it by using the combination of movement, number keys and 
spin keys.

Set_Short_Integer -  A procedure which allows the user the ability to alter the word 
size integer passed to it by using the combination of movement, number keys 
and spin keys.

Set_Integer -  A procedure which allows the user the ability to alter the medium size 
integer passed to it by using the combination of movement, number keys and 
spin keys.

Set_Long_Integer -  A procedure which allows the user the ability to alter the long 
size integer passed to it by using the combination of movement, number keys 
and spin keys.

Set_Real -  A procedure which allows the user the ability to alter the real number 
value passed to it by using the combination of movement, number keys and spin 
keys.

Get_Byte - A procedure which allows the user the ability to enter a byte size integer 
by using a entry method similar to that of an electronic calculator.

Get_Word - A procedure which allows the user the ability to enter a word size 
integer by using a entry method similar to that of an electronic calculator.

Get_Short_Integer - A procedure which allows the user the ability to enter a short 
size integer by using a entry method similar to that of an electronic calculator.

Get_Integer - A procedure which allows the user the ability to enter a medium size 
integer by using a entry method similar to that of an electronic calculator.

Get_Long_Integer - A procedure which allows the user the ability to enter a long 
size integer by using a entry method similar to that of an electronic calculator.

Get_Real - A procedure which allows the user the ability to enter a real number 
value by using a entry method similar to that of an electronic calculator.

Get_String - A procedure which allows the user the ability to enter a string of 
character by using a entry method similar to that of an electronic calculator.

Change_Boolean - A procedure which allows the user the ability to alter a Boolean 
value by using the 't' and 'f' keys and the space key as a toggle.

Functions

Convert_To_String - (Convert data to string) - This function converts the data in 
source into a string. Source can be an array of bytes, characters or any type of 
record.

Chapter 8

The FileMem unit

Version 2.4

        The FileMem unit is a unit designed to provide a better interface and more versatile ran
dom access secondary memory system.  In more easily understood terms, this means that it 
provides a sort of simulated virtual memory system (targeted on the drives) for the program 
using the disk operating system.  Whew!  That's a mouthful of information!
        Now, I know what you're thinking.  What the heck is this, and why would I want to such 
a monstrous thing?  Well, the answer is simple;  Sooner or later, you're going to write a large 
program and DOS is going to balk at the amount of memory your program requests from it.
        So what does FileMem do?  FileMem blends the distinction between primary memory 
(Random Access Memory or RAM) and secondary memory (Disks), plain and simple.
        So what's the advantage of using it?  The advantage is straightforward, first there is size.  
FileMem uses the disk for data storage and as everyone knows, there is far more disk space 
on the system (typically) than there is primary memory (RAM).
        So why don't I just use a file?  You could, and FileMem does, but your standard file sys
tem doesn't have the features that FileMem adds.
        Such as?  FileMem uses a temporary file to add things to the file system such as automat
ic file space requesting, space management and discarded space tracking.
        What does all this mean?  Basically, it means that if you use FileMem the way it is in
tended to be used, you don't have to worry about this.  FileMem is designed to allow you to 
do on disk things you could only do in memory before, such a building complex data struc
tures and managing them.  FileMem works on the disk like a temporary memory system.  
FileMem handles the gory details of space allocation and deallocation and record polling.
        FileMem works hard to manage your data safely and effectively and it's all automatic. 
And as an extra bonus, FileMem does it's own disk buffering if you allow it.

How does it work?
        
        FileMem either uses the current directory area of the current disk to create a temporary 
file for it's own use or creates an original file in the directory specified by the environmental 
variable TEMP.  For the record, this temporary file grows larger as you need it.  Be 
forewarned that by using file space, FileMem is naturally slower than using main system 
memory.
        FileMem also includes a specially designed in-memory disk buffering system that speeds 
up the access time considerably.  The buffering system uses system memory, but is designed 
to give up that memory to your program when it asks for it.
        FileMem's buffering system works on a last served higher status policy.  This means that 
the most recently accessed record is put on the top of the list and the least recently accessed 
record moves to the bottom.  The bottom memory space is the first to be tossed out when 
new memory is requested. (This doesn't mean the data is lost, only that it won't be stored in 
main memory any longer)
        For safety's sake, FileMem creates it's own temporary file before the program begins 
executing.  In this way, the program can begin using FileMem from the very beginning and 
the file handle always remains open.
        And finally, FileMem through Turbo Pascal's (R) exit routine linkage, remembers to 
close it's file and delete it from the directory when it's finished.  In this way, save for a major 
system crash, FileMem doesn't leave garbage lying around.  Note:  If FileMem is set up to 
always uses the same file name, in the unlikely event the temporary file is left on the disk, 
FileMem will overwrite the old file when the program is run again from the same directory.
        FileMem relies upon the DOS unit to handle it's file support and on Generate_FileName 
to handle the details of the temporary file name in the Temp directory..

Are there any limitations?

        By using long integers size pointers, DOS gives the file system a lot of room to work 
with.  In Microsoft's (R) disk operating system, files are usually limited by the size of the 
available disk space.  Since Turbo Pascal (R) uses the long integer variable to handle file 
pointers, the amount of addresses handled by the file system is somewhere in the 
neighborhood of 2 billion byte sized records. Therefore, the theoretical maximum amount of 
file storage is roughly 2 gigabytes.  The practical maximum is somewhat less than available 
disk space.
        Chunks of data that are allocated by FileMem are created in sizes ranging from the mini
mum size (6 bytes) to the maximum size. (Maximum value of 32765 in DOS or 100000 in 
OS/2)
        Performance:  Performance is mostly based on the speed of access from the request for 
disk data to the delivery of it.  The performance factor resulted in the decision not to allow 
block blending and to implement a hashed link list table for tracking.  However, the nature of 
file accessing provides the most limits on the performance of this system.  Aside from get
ting a faster hard drive or more memory, here's a couple ways to increase performance...
        Define more buffers in the operating system.
        Use a disk buffering system such as SmartDrv.

How to use

        FileMem's use is straightforward and simple.  First you have to allocate the file space on 
the system by using the New_Pointer function.  You must determine the size of the record 
you want to use and pass that information to the function as you allocate the function.  The 
function returns a pointer to you that points to the allocated file space.
        After the space is allocated, you put your data in the system using the Put_Data proce
dure.  There is also another procedure called Put_New_Pointer which does both the alloca
tion and initializing at the same time.
        After the data is allocated and initialized, you can use the Get_Data procedure to call up 
the data at any time.  All you pass to Get_Data is the address of the data you which to read 
and your data is returned to you through the specified variable.  You are also free to update 
this data at any time using the Put_Data routine.
        Finally, when you're all through with your record, you can deallocate the disk space by 
using the Dispose_Pointer routine.  This routine returns the data space to the system so that it 
can but put on the deallocation list.
        Warning!  Manipulation of the specified pointers is definitely not recommended due to 
the fact the pointers are always verified before use.

Which compilers are supported?

        The FileMem unit has been tested and found to compile correctly under Turbo Pascal (R) 
versions 4.0 through 6.0.  FileMem has been expanded to compile under Speed Pascal/2 (R) 
version Beta 4 with larger memory block sizes.

Constants

Allow_Buffering - This switch turns on the generation of code that buffers the file 
data in the system memory.

Immediate_Write - This switch generates code that immediately writes data to the 
file.  Otherwise the code generated waits until the last possible moment before 
writing the data.

Generate_Unique_File - This switch alters the method of obtaining a file name for 
the temporary file.  When true, the system uses a unique file name in the TEMP 
directory, when false it operates the old way using File_Name in the current 
directory.

File_Name - This constant is the default name that the system uses to create it's 
temporary file.

Types

Pointer_Type - This defines the pointer type used by the system.  Long Integers al
low the most accurate addressing.

Procedures

Put_Data - (Put data on disk)  This procedure copies the included data to the disk 
file at the given address.

Get_Data - (Get data from disk)  This procedure retrieved the data from the speci
fied disk address and copies it into the given variable.  Care must be taken to 
ensure the variable can hold all the data, since this routine doesn't check.

Get_Buffer_Data - (Get buffer data from disk)  This procedure copies data from the 
disk at the given address to the given variable.   

Dump_Deallocated_Listings - This debugging procedure prints out a report to the 
specified file that contains all the data blocks that have been disposed and are 
still available.

Flush_Buffers - (Flush the buffers)  This procedure flushes out all the memory buff
ers to disk. 

Peek_Data - (Peek data from disk)  This procedure copies the data from the speci
fied disk address into the variable bypassing the memory buffer.

Peek_Buffer_Data - (Peek buffer data from disk)  This procedure copies the data 
from the specified disk address into the variable bypassing the memory buffer.

Functions

New_Pointer - (Allocate data block) This function attempts to allocate the specified 
amount of space on the disk for the calling routine.  If it's successful, it returns a 
pointer to reference that space.  If there is no more disk space available, it will 
return a null pointer.

Put_New_Pointer - (Allocate and initialize data block)  This function attempts to allo
cate the specified amount of space on the disk for the calling routine.  If it's suc
cessful, it returns a pointer to reference that space and puts the data in the 
space.  If there is no more disk space available, it returns a null pointer.

Dispose_Pointer - (Deallocate the data block)  This function returns the data block 
address to the system for later reusing.

Chapter 9

The FillCode unit

Version 1.0

        Although new to this library, FillCode is a unit with which I've been working with for 
some years now so that means is reasonably stable.  FillCode is an underlying unit that 
supports and in fact is closely tied to the Draw unit.  Basically, it includes most of the 
support routines for building graphical objects.
        I decided to dedicate a chapter to the FillCode unit, because there are some incidents 
when direct contact with this unit can be very beneficial.  Even my Draw_Demonstration 
program makes direct use of it.
        Okay, to get to the heart of the matter, FillCode is designed to take over the task of 
collecting the lines that are to be drawn on the screen.  The data is stored in a special 
dynamic data structure until the results are ready, then all the lines are dumped onto the 
screen at one time.

How does it work?

        This system is an inseparable part of the draw unit.  It is best to use it directly only for 
purposes beyond the capabilities of it's brother unit.
        The FillCode unit builds a hash table of ordered linked lists to represent various pars of 
the screen pixels.  Each element on the table represents the beginning and ending of a fill line 
as a single pixel hashed on the basis of the Y coordinate.  By ordering the pixels on a X 
coordinate basis, it's very easy to keep track of what goes where. Also note that the pixel 
colors are determined by the draw system at the time of the screen dump.
        There are three steps to completing a picture using FillCode...
          1 - The list must be cleared of any data from a previous drawing.
          2  - By use of numerous calls to the filled pixel routines, the drawing is rendered in the   
                data structure.
          3 - The drawing is transferred to the graphical rasper display by a means clearing out 
the             dynamic structure's list.
        This unit depends on the draw unit to which it owes it's co-dependence.

Are there any limitations?

        Note that this unit generates a dynamic data structure.  That means a lot of data is stored 
in linked lists on the heap.  It is possible and even very likely on tremendously complex 
drawings to deplete the heap until there isn't enough memory to continue.

How to use

        I'm not really going to go into much detail about the use of this unit because of the fact 
that most of the setting up is supposed to be done through the Draw unit.  However, I'll 
include a description here on using various parts of the FillCode routines.  For more 
information, please take a good look at the demonstration program for the Draw unit.
        In this example assume everything is within the body of your procedure's begin and end 
bracket.

        ...
        Clear_List;
        ...

        This routine clears the list to begin the drawing of a new object.  In the next piece of 
code, we're going to draw two end elements in the drawing buffer.

        ...
        Filled_Pixel( 1, 1 );
        Filled_Pixel( 100, 1 );
        ...

This piece of code put pixels immediately on the first line at locations 1 through 100.  In this 
next example, the results will be saved until the draw routine is enabled.

        ...
        Filled_Pixel_Job( 1, 1 );
        Filled_Pixel_Job( 1, 200 );
        Filled_Pixel_Job( 1, 146 );
        Filled_Pixel_Job( 1, 74 );
        Draw_List;
        ...

        This last example draws a line on the first line of the screen from 1 to 74, and from 146 
to 200.  Note that the order the pixels are plotted are not important, only their location and 
number.  

Which compilers are supported?  

        This unit is designed and has been tested to compile successfully under Turbo Pascal's 
(R) versions 5.0 through 6.0.  The limitation is mostly a result of the two routines 
interdependence with each other.  Some of this code may very easily be rewritten to work 
with the earlier compilers.

Procedures

Swap -  This procedure switches two integer values with each other.

Clear_List -  This procedure clears the entire work data structure.

Clear_Y_Coordinate_List -  This procedure clears only the y coordinate list and 
nothing else.

Filled_Pixel -  This procedure enters a pixel into the data structure and produces 
immediate results if possible.

Filled_Line -  This procedure enters two pixels into the data structure and produces 
immediate results if possible.

Filled_Pixel_Job -  This procedure enters a pixel into the data structure but will not 
produce immediate results.

Filled_Line_Job -  This procedure enters two pixels into the data structure but will 
not produce immediate results.

Draw_List -  This procedure is designed to flush out the data structure and draw the 
completed display on the screen.

Chapter 10

The Fraction unit

Version 1.0

        The Fraction unit contains a collection of  simple calculation values that use fractions.  It 
is designed to allow the system to perform numeric operations using fractions in a straight 
direct format instead of as real numbers which can easily lose accuracy with sometimes even 
the simplest numbers.
        By using fractions, a programmer can achieve a much higher precision in certain calcula
tions.  The use of this unit helps to eliminate the type of accuracy errors that often results 
with the use of real numbers.

How does it work?

        The Fraction unit performs operations on fractions in a manner very similar to that which 
you probably learned in school.  The operations are performed on both parts of the fractions 
and the results are reduced to lowest terms.  For accuracy sake, the numbers worked with in
ternally are long integers.

Are there any limitations?

        For the sake of function results, the calculation results are limited to what can be passed 
back in the form of a function.  While before, Turbo Pascal allowed function results to be 
records, when the compiler switched over to version 4, record results were no longer support
ed.  For this reason, I switched the results over to long integers which just so happened to be 
able to hold two regular integers internally.
        But by this very same token, the new compiler would disallow the use of long integers in 
a record and the routines could not be improved to increase accuracy.  Therefore the limit is 
what can reasonably be represented by an integer and a word. 

How to use

        Fractions is fairly straightforward and easy to use. (unless you happened to have slept 
through their introduction during school)  Simply define your variables as Number_Type and 
use the assignment and calculation routines to perform the calculations.  To convert a value 
into something more readable, use the conversion routines.
        Example...

Var
  Number1,
  Number2,
  Number3: Number_Type;

Begin
  ...  
 { Set Number1 to 1/8. }
  Number1 := Equals( 1, 8 );
 { Set Number2 to 3/5. }
  Number2 := Equals( 3, 5 );
 ...
  Number3 := Add( Number1, Number2 );
  Number3 := Subtract( Number1, Number2 );
  Number3 := Multiply( Number1, Number2 );
  Number3 := Divide( Number1, Number2 );
  ...
End.

Which compilers are supported?

        The Fraction unit has been tested and  determined to compile correctly with Turbo Pascal 
(R) versions 4.0 through 6.0.  The Fraction unit has been tested and found to compile 
correctly with Speed Pascal/2 Beta 4.  Surprisingly it needed absolutely no modifications and 
still benefited from 32 bit code.

Types

Number_Type - This integer is redefined internally as the fraction record.  This is the 
form passed by the routines and the form the compiler has to handle.

Procedures

Separate - (Separate the value)  This procedure takes a fraction type value and 
separates the numerator from the denominator for whatever reason it's needed.

Functions

Equals - This function combines the numerator and denominator together into the 
record redefined as Number_Type.

Convert_To_String - This function takes a fraction type value and converts it into a 
string for convenient output.

Convert_To_Real - This function takes a fraction type value and converts it into a 
real value.

Add - (Add two fractional numbers)  This function returns the sum of the first and 
second fractional numbers.

Subtract - (Subtract two fractional numbers)  This function returns the result of sub
tracting the second fractional number from the first.

Multiply - (Multiply two fractional numbers)  This function returns the product of the 
first and second fractional numbers.

Divide - (Divide two fractional numbers)  This function returns the result of dividing 
the second fractional number from the first.

Chapter 11

The Generate_FileName unit

Version 1.0

        The Generate_FileName unit is a simple support unit for some of the other units that 
need to open temporary files with a unique name.

How does it work?

        The Unit is designed to generate a unique file name particularly in the system's 
temporary file sub-directory.  First it checks the system's environment for the temporary file 
element. (Not with compiler version 4.0) This is usually under the name TEMP or TMP.  
This value is assumed to hold a valid path-name to the temporary sub-directory.  Next it 
generates a filename using a number sequencer.  If a file by that same name exists, the 
program uses the  next higher number and so on.
        This unit depends on Turbo Pascal's (R) DOS unit to perform system disk operations.

Are there any limitations?

        Except for the limitation with compiler version 4.0, there are no currently known 
limitations to the Generate_FileName unit except for the fact that it will probably fail if the 
environmental value of TEMP is wrong or there are a great deal of temporary files in the 
directory with the same names as the unit is generating..

How to use

        Using the Generate_FileName unit is very simple.  First, of course, you must declare to 
the compiler that you intend to use it.  This is very easy.  Simply insert the name of the unit 
in your programs uses clause.  Example:

...
Uses
  Generate_FileName;
...

        Next, somewhere in your code where you will want to generate a temporary file you 
simply use the function provided.  Here, assume Temporary is a string variable and InFile is 
a file of any type.

...
Begin
  ...
  Temporary := Generate_Unique_FileName;
  ...
  Assign( InFile, Temporary );
End.

        See!  That's all there is to it.  After the unique file name is generated, all you have to do is 
open it and uses it.  This example compresses the previous one.

  ...
  Assign( InFile, Generate_Unique_FileName );
  ...

        And that's it!  Happy programming.

Which compilers are supported?

        The Generate_FileName unit has been tested and  determined to compile correctly with 
Turbo Pascal (R) versions 4.0 through 6.0.  It's also been found to compile and operate under 
Speed Pascal/2 version Beta 4.

Functions

Generate_Unique_FileName - Returns a string identifying a unique filename and 
path that may be used to open a temporary file.

Chapter 12

The Indicators unit - (Indicato in Speed Pascal/2)

Version 1.22

        Indicators is a small unit that holds a couple routines which you may find useful for creat
ing percentage gages and other graphical objects on the monitor screen.  Indicators defines 
two type of percentage gages; a horizontal one and a vertical one.
        A Percentage gage is a box graph of percentage points displayed on the screen.  You'll 
find them everywhere in all sorts of different programs because they're very useful for dis
playing an easy to read chart of the amount of processing done and the amount that remains 
to be completed.
        Indicators also holds a routine that offers the user the ability to choose a text attribute for 
use in your programs.  The attribute routine allows the user the opportunity to chose which 
ever attribute text and background color combination that he or she thinks works best.

How does it work?

        The graph routines merely use the machine block drawing characters to create the bar 
graph on the screen.  The programmer supplies the appropriate location and the size of the 
graph and the routine does the rest.
        The attribute routine simple maps the attributes onto the screen and allows the user to 
pick the attribute combination by using the arrow keys.  If escape is pressed, the attribute re
mains unchanged, otherwise the routine changes to the newly selected attribute.
        Indicators uses the CRT unit and relies on the Core, KeyBoard and String_Utilities units.

Are there any limitations?

        There aren't many limitations to the code in Indicators.  But there are a couple.  First and 
foremost, none of the routines in Indicators are designed to be used in the graphic modes, so 
I'm not going to guarantee they will work.  Try them out for yourself and see what happens.
        Second, the parameters passed to the bar graph routines must be valid for the routines to 
operate correctly.  The routines, for the benefit of speed, have very little error checking so it's 
the programmer's responsibility to ensure that only correct values are provided to them.  
Normally, this is not a problem if your program generates the codes.  
        In addition, this unit is expected to be expanded in the future with new and more com
plex graph systems.  So don't count on anything inside the unit staying the same, except the 
external declarations.

How to use

        Now to use the procedure to allow the user to pick his or her own text attribute.  First the 
unit must be declared in the uses clause of your unit or program.  Of course this is done by 
using the compiler's uses clause.  Simply add the unit's reference like so.

Uses
  Indicators;

or, if you're using Speed Pascal/2 use this statement.

Uses
  Indicato;

        Now for the purposes of our demonstration, we're going to define a variable to pass to the 
Change_Attribute routine.  The Attribute must be defined somewhere in your program as a 
variable, or perhaps a variable constant.  Strict constants are not supported.  

Var
  Attribute: Byte;

        Finally, in our example program we must initialize the variable before it can be passed to 
the attribute changing routine. If we skip this test, the user still has the opportunity to alter it, 
but may skip out.  Be forewarned that the Change_Attribute routine generates a large amount 
of screen output so the current screen window must be large enough for it to operate properly 
and the screen must be cleaned up afterwards.

Begin
  ...
  Attribute := 7;
  ...
  Change_Attribute( Attribute );
  ...
End.

        Okay, that's how the Change_Attribute routine works.  Let's try something different.  The 
bar graph routines operate in a fairly straightforward manner too. Here is example code so 
that you can see how it's done.  This example puts the bar graph on the top row and covers 
forty characters or half the normal text screen.

Var
  Value: Byte;
...
Begin
  ...
  Side_Bar_Graph( 1, 1, 40, Value );
  ...
End.

        That's all there is to it.  Please note that somewhere the value of Value should have been 
initialized, or what's put on the screen isn't worth much.  Still, it was easy wasn't it?

Which compilers are supported?

        Indicators has been tested and determined to compile correctly under Turbo Pascal (R) 
versions 5.0 through 6.0 and with Speed Pascal/2 version 1.5.

Constants

????_Background - These constants define the possible color of the screen attribute 
background for use with the duel graphing procedures.  (Black, Blue, Green, Cyan, 
Red, Magenta, Yellow and White)

????_Character - These constants define the possible color of the screen attribute 
foreground for use with the duel graphing procedures. (Black, Blue, Green, Cyan, 
Red, Magenta, Brown, Light_Gray, Dark_Gray, Light_Blue, Light_Green, Light_Cyan, Light_Red, 
Light_Magenta, Yellow, White and Flashing) and for the MGA. (No, Dim, Dim_Underlined, 
Bright, Bright_Underlined and Reverse_Video)

Bar1_Color - This variable constant defines the color of the lower graph in the duel 
bar graph.

Bar2_Color - This variable constant defines the color of the upper graph in the duel 
bar graph.

Bar_Background - This variable constant defines the color of the background in the 
duel bar graph.

Procedures
 
Change_Attribute - This procedure, designed to compliment the CRT unit, offers the 
user a map of the possible text attributes from which to select a satisfying choice 
using the arrow keys.

Side_Bar_Graph -  This procedure produces a horizontal bar graph on the text 
screen using block characters.

Tall_Bar_Graph - This procedure produces a vertical bar graph on the text screen 
using block characters.

Duel_Side_Bar_Graph - This procedure draws a duel horizontal bar graph on the 
screen at the given location using the predefined text and background attributes.

Duel_Tall_Bar_Graph -  This procedure draws a duel vertical bar graph on the 
screen at the given location using the predefined text and background attributes.


Function

Calculate_Percentage - This function calculates the percentage value from two 
given long integers.  The result is a byte value from 0 to 100.

Chapter 13

 The JoyStick unit

Version 1.1

        The JoyStick unit creates a front end Turbo Pascal (R) interface for the BIOS JoyStick 
routines.  It's purpose is to make it easy to add joystick support to your program.  Joystick is 
also designed to provide a better and more accurate joystick reading than what is normally 
obtained.

How does it work?

        The JoyStick unit works by using the system calls of the BIOS to read the joystick val
ues.  After the values are obtained, they are mathematically averaged in order to eliminate 
the constant shifting that usually occurs from such sensitive devices.
        The results are made available to your program through the appropriate routines, or if 
you prefer using the keyboard, the joystick values are routed as cursor and enter commands 
through the KeyBoard unit. (Compiler versions greater than 4.0)  
        The JoyStick unit depends on Turbo Pascal's (R) DOS and CRT unit and also links up to 
the KeyBoard unit with compiler versions greater than 4.0

Are there any limitations?

        The BIOS joystick service was not implemented by IBM (R) on their PC's prior to 
11-8-1982.  This unit is not likely to operate properly when being used on machines built 
before this date.
        This unit links up with the KeyBoard unit to provide the ability of the joystick to operate 
cursor movement commands.  While it and Pointer can work nicely together in your pro
gram, and I haven't encountered any interference from each of them, using them both togeth
er in a program is not recommended.

How to use

        The JoyStick unit is fairly easy to use.  First, of course, you must declare the JoyStick 
unit name in your uses clause.  Then, if you're using a Turbo Pascal (R) compiler greater 
than 4.0, you should find that you can control the movement of the cursor using your joy
stick.  
        Other than that, getting values directly from the unit routines are also easy.  First and 
foremost, you should include a line in your code that initializes the joystick.  Set_Joystick is 
the routine that handles this.  The values are returned as positive or negative integers which 
very depending upon which direction the joystick is pointed in.  Button values are returned 
in Boolean variables depending upon weather they are pressed or not. 
        Then you can call the read joystick routine whenever you wish to poll the activity of the 
joystick.
        Heres an example piece of code.

...
Uses
  JoyStick;
...
Var
  Stick1,
  Stick2: Stick_Type;
...
Begin
  ...
  If not Set_Joystick
    then
      WriteLn( 'BIOS Joystick Interface is not operating ' );
  ...
  Read_JoyStick( Stick1, Stick2 );
  ...
End.

Which compilers are supported?

        The JoyStick unit has been tested and found to compile satisfactory using Turbo Pascal 
(R) compilers 4.0 through 6.0.

Constants

Adjust -  This byte value is used to mathematically reduce the value of the joysticks 
reading value and eliminate the drift that occurs.  Optimal value is somewhere 
around 5.

Delay_Amount - This value is used to simulate the type of delay produced by the 
keyboard.  Otherwise, the joystick produced values would overwhelm the system 
and accurate control would be lost.

Types

Stick_Type -  Defines a record structure that is used by the joystick routines to re
turn the current value of the joystick.
  
Procedures

Read_JoyStick - (Read the joy stick)  This procedure returns the status of the joy
stick at the time it's called.

Functions

Set_JoyStick - (Set the joy stick)   This function sets up the initial values of the joy
stick unit for adjustments later on.

Chapter 14

The Keyboard unit

Version 2.2

        The keyboard unit is a unit created for gathering information from the keyboard for use 
by several of the others units in the library.  It's intended use and possibly it's greatest 
strength, is that it was primarily intended to be used by the other units as a consistent method 
of direct keyboard input.
        The keyboard unit, however has other redeeming features as well.  As it polls the key
board for input, it allows an alternative routine (Only when compiled with Turbo Pascal (R) 
compiler versions above 4.0) to be executed over and over again.  It also features a peeking 
routine which you may find useful, that returns the status of the keyboard toggle switches.
 
How does it work?

        The Keyboard unit works with a simple design.  The main unit is designed to wait for 
and accept input from the keyboard in the form of commands.  Commands are defined as 
single or multiple keystrokes.  The routine then decodes the commands and returns them as a 
value to the program.
        In this way, several alternative methods are available to issue the same command and the 
program doesn't have to bother checking for all of them because this unit handles it.  The 
unit also accepts your own routine (compiler versions greater than 4.0)  for use during the 
waiting time.
        This unit has been expanded to allow the inclusion of commands from the alternate input 
devices.  Also note that some of the routines in this unit are order dependent.
        This unit relies on Turbo Pascal's CRT and DOS units. 

Are there any limitations?

        Keyboard doesn't have many limitations except for it's lack of extensive error checking 
code.  This was designed to ensure a much higher execution speed.

How to use

        Keyboard is automatically included if your program uses any of the other units that call 
upon it.  Otherwise, just include the Keyboard reference in your Uses clause.
        After this, you merely call the appropriate routines when you wish to access data from 
the keyboard.

Which compilers are supported?

        The keyboard unit has been determined to be compilable using Turbo Pascal versions 4.0 
through 6.0.

Constants

Press_??????? - These constants are the keystroke command codes returned by 
the Get_Command routine.  Each one differs by the required keystrokes neces
sary to invoke it. (See the unit header)

Pressed_??????? - These constants are the extended keystroke command codes 
returned by the Get_Command routine.  Each one differs by the required key
strokes necessary to invoke it. (See the unit header)

Pointer_???????? - These constants are the expanded command codes returned 
by the Get_Command routine when input is intercepted from one of the alterna
tive input units.  The codes are varied from the position of the cursor from the 
pointer or the status of the pointer buttons. (See the unit header)

Outside_???????? - These constants are the expanded command codes returned 
by the Get_Command routine when input is intercepted from one of the alterna
tive input units.  The codes are varied from the position of the pointer to the cur
rent CRT window. (See the unit header)

On_Frame_??????? - These constants are the expanded command codes returned 
by the Get_Command routine when input is intercepted from one of the alterna
tive input units.   The codes are varied from the position of the pointer to the cur
rent CRT window. (See the unit header)
          
Variables

Key_Shift - This Boolean value is set to true by the Peek routine if one of the shift 
keys were pressed when it was called.

Key_Insert - This Boolean value is set to true by the Peek routine if the system was 
set in insert mode when it was called.

Key_Number - This Boolean value is set to true by the Peek routine if the number 
lock key was on when it was called.

Key_Scroll -  This Boolean value is set to true by the Peek routine if the scroll lock 
key was on when it was called.

Key_Capital -  This Boolean value is set to true by the Peek routine if the capital lock 
keys was on when it was called.

Key_Control -  This Boolean value is set to true by the Peek routine if one of the 
control keys were pressed when it was called.

Key_Alternate -  This Boolean value is set to true by the Peek routine if one of the 
alternate keys were pressed when it was called.

Key_Number_Lock - This Boolean value is set to true by the Status routine if the 
system was in the number lock state when it was called.

Key_Scroll_Lock - This Boolean value is set to true by the Status routine if the sys
tem was in the scroll lock state when it was called.

Key_Insert_Lock - This Boolean value is set to true by the Status routine if the sys
tem was in the insert state when it was called.

Key_Capital_Lock - This Boolean value is set to true by the Status routine if the 
system was in the capital lock state when it was called.

Keys - This file is opened by the unit to allow the other units to access the keyboard 
even when the standard input file is redirected.

The following variables are defined with Turbo Pascal (R) versions greater than 4.0 
to allow linking to the descendent units.

Lock_Routine - This variable procedure is replaced by the lock unit to allow locking.

Wait_Routine - This variable procedure is called by Get_Command while it's waiting 
and there isn't anything to read from the keyboard.  Unit's are free to replace this 
variable if they take care to replace it when they are finished.

Alternative_Input -  This variable function is called by Get_Command to gather infor
mation from an alternative input device.  It's a link handle and is used by Pointer 
or Joystick to send input to the keyboard unit.

Cursor_Row - This byte value is furnished for the benefit of the alternative input rou
tine to determine the cursor position.

Adjust_Amount - This byte value is furnished for the benefit of the alternative input 
routine to determine the cursor block position.

Cursor_Column_Start - This byte value is furnished for the benefit of the alternative 
input routine to determine the block cursor position.

Erase_Pointer - This variable procedure is provided for the descendent unit routines 
to allow alternative input units to clean up after themselves.
 
Update_Control - This variable procedure is provided for the descendent unit for 
various purposes.

Allow_Control - This Boolean variable is set by the descendent units to alter the 
processing flow of this unit.

Procedures

Get_Command - This procedure retrieves input data from the keyboard and returns 
a value referring to the type of data received, or a value indicating the command 
request.

Status - This procedure sets a bunch of flags to correspond to the current value of 
the keyboard toggle keys.

Peek - This procedure sets a bunch of flags to correspond to the current value of the 
keyboard immediate status.
 
Functions

Data_Ready - This function returns true only if there is data, either keyboard or alter
native input ready to be read by the Get_Command procedure. 

Chapter 15

The Lock unit

Version 1.01

        The Lock unit is a special unit designed to perform a system lock up for the program 
while the user is away from the system.  It features a simple system that takes a user defined 
password and locks up the computer until someone reenters that password back into the pro
gram.  Until that time, the only way to access the system is to reboot it.  

How does it work?

        The Lock unit provides a procedure that takes over the system when called.  It opens a 
window on the screen (Text mode preferably) and takes the password.  Then after the pass
word is entered, it waits, drawing a simple animation on the screen until the very same pass
word is reentered before ending and returning control back to the program.
        The Lock unit displays a simple bouncing cursor animation to signify it's working and 
waiting for the user to reenter the password.
        The Lock unit depends on the CRT unit and uses the Core and Keyboard units.

Are there any limitations?

        The animation routine doesn't work very well in graphic modes and under the current 
version of Speed Pascal/2, the reassigning of the Input file can throw the system off.

How to use

        After defining the unit in the uses clause, the unit is fairly easy to use.  It's invoked by 
calling the Lock procedure in your program code.  The lock routine is also supplied to the 
core unit so that other units that use core can directly access it if it's used in the program.  
Menu and Editor are examples of units that include direct access to it. 

Which compilers are supported?

        This unit was created to compile under Turbo Pascal version 5.0.  It should compile 
properly with all successor compilers as well.  This unit has been enhanced to compile 
properly under Speed Pascal/2 version 1.5.  

Constants

???????_Background - These color constants are defined to make it easy to specify 
the color of the window background. (Black, Blue, Green, Cyan, Red, Magenta, 
Yellow & White)

???????_Character - These color constants are defined to make it easy to specify 
the color of the window text.  (Black, Blue, Green, Cyan, Red, Magenta, Brown, 
Light Gray, Dark Gray, Light Blue, Light Green, Light Cyan, Light Red, Light Ma
genta, Yellow & White)

Flashing - This constant is defined to make it easy to specify text that is flashing.  
(Doesn't work in graphic modes)

No_Character - This constant is defined to make it easy to specify the text attribute 
in monochrome mode.  This produces a black character on a black background.

Dim_Underlined_Character - This constant defines a dim character with underlining 
on a black background in monochrome mode.

Dim_Character - This constant defines a dim character on a black background in 
monochrome mode.

Bright_Underlined_Character - This constant defines bright characters with underlin
ing on a black background in monochrome mode.

Bright_Character - This constant defines bright characters on a black background in 
monochrome mode.

Reverse_Video_Character  - This constant defines a black character on a bright 
background in monochrome mode.

Open_Attribute - This variable constant defines the initial color of the window.  Feel 
free to alter it if you wish.

Enter_Attribute - This variable constant defines the initial color of the password input 
prompt.  You may also alter this if you wish.

Message_Attribute - This variable constant defines the color of the messages.  This 
also may be altered if desired.

Animation_Attribute - This variable constant defines the color used for the bouncing 
ball animation routine.  Again, alter this if you wish.

Procedures

Lock_Up - This procedure is the main routine which locks up the program.

Chapter 16

The Matrices Unit

Version 1.0

        The Matrices unit is a handy little collection of routines which performs arithmetic pro
cesses involving matrices. (Matrix arithmetic)  For those of you who know what to do with 
matrices, you might find this collection of routines very helpful in your graphic or scientific 
programs.
        The Matrix unit allows you to define matrix arrays of sizes up to what the maximum ma
trix size is defined as.  The Matrices unit uses real numbers (Floating point approximations) 
to represent the numbers in memory. This provides increased accuracy, but also uses more 
memory and sometimes produces rounding errors.  Also take note that the size of the matrix 
limit is partially determined by the system (The segment limit) and the size of the variables. 
(Bytes per number)   
        Also note that this unit is designed to use the types associated with the math coprocessor 
if the compiler is set to use them.  Error checking in the matrix operations is set up to per
form as best as possible, but note that overflows and underflows may still occur.   All the 
standard matrix operations are supported and the routines are designed to allocate as little 
memory as possible.

How does it work?

        Matrices are first allocated for use using the allocate matrix function.  Only after they are 
allocated can they be initialized and used by the various routines.  When the matrices are no 
longer needed, you can discard them using the supplied deallocation routine.
        Since matrices are created using pointers, matrices of different sizes can be created on the 
fly for use by your programs as they need them.  I'm positive that you'll find this a great fea
ture of versatility and convenience for your programming use.

Are there any limitations?

        There are several limitations that should be pointed out.   First, the error checking in 
some of the code is somewhat limited especially in results that can possibly create an over
flow or underflow.  Since these are unavoidable, take care to work around them if possible.   
Also watch out for rounding errors on the last digits.  Binary numbers do not translate as ac
curately to decimal numbers as one could hope.
        Also note that when calculating the determinate for very large matrices, using the fast 
method can easily generate overflows and halt the program.  I've tried to include code to 
compensate for this fact, but the result can still occur on the larger of the matrices.  (Sizes 
over 14 and 15 numbers)

How to use

        The use of the Matrices unit is fairly easy.  First, you must include the name of the unit 
somewhere in your uses clause.  Then you must define a matrices pointer to allocate a matrix 
for use.  After the matrix is allocated, you can initialize it and use it as you wish.  Finally, 
when you're all done, don't forget to discard the matrix pointer so that the memory is avail
able for use later by some other process.
        Heres a abbreviated example...

Uses
  Matrices;
...
Var
  Matrix: Pointer;
...
Begin
  ...
  Matrix := Allocate_Matrix( 2, 2 );
  ...
  Put_In_Matrix( Matrix, 1, 1, 1.23434 );
  Put_In_Matrix( Matrix, 1, 2, 8.43848 );
  Put_In_Matrix( Matrix, 2, 1, 3.38485 );
  Put_In_Matrix( Matrix, 2, 1, -3.38485 );    
  ...
  Write_Out_Matrix( Output, Matrix );
  ...
  WriteLn( Determinate_Fast( Matrix ) );
  ...
End.

Which compilers are supported?

        This unit has been determined to compile under Turbo Pascal (R) version 4.0 through 
6.0.  Please also note the the maximum real and extended values supported by each compiler 
version differ from each other.  This unit also has been tested to compile and operate under 
Speed Pascal/2 version 1.5.

Constants

Max_Matrix_Size -  This constant defines the largest supported matrix size of the 
code.  This value can be increased to a number depending upon the compiler 
and the amount of bytes per number type.

Maximum_Matrix_Number -  This constant depends on the compiler version you're 
using and weather or not you're using the math coprocessor value types. 

Types
    
Matrix_Number -  This type is used to define the storage basis of the matrix.  If the 
compiler is set to use the coprocessor, this type is set to extended, otherwise this 
type is going to be set to Real.

Procedures

Deallocate_Matrix -  (Deallocate the matrix)  This procedure allows you to return the 
memory used by the matrix back to the memory pool.

Get_Size -  (Get the size)  This procedure takes the given matrix variable and re
turns it's size in terms of rows and columns.  Useful for comparing sizes of two 
matrices.

Put_In_Matrix -  This procedure places the specified value into the matrix at the se
lected row and column location.  This is probably the routine you'll use most for 
initializing matrices.

Read_In_Matrix -  (Read in the matrix)   This procedure allows you to read in a ma
trix from a text file.  The routine expects the matrix to be encoded in a standard 
format.  Opposite of Write_Out_Matrix.

Write_Out_Matrix -  (Write out the matrix)  This procedure allows you to write the 
given matrix out to a text file in the standard formation.  Opposite of 
Read_In_Matrix.

Solve_Matrix - (Solve the matrix)  This procedure solves the given matrix and re
turns the result in the first row.  Solving X variables with X unknowns.

Generate_Matrix -  This procedure generates a random matrix with values ranging 
from negative to positive one thousand.  Useful for random fluctuations.

Functions

Allocate_Matrix -  (Allocate the matrix)  This function allocates the memory to hold a 
matrix and returns the address to fit the given parameters.

Copy_Matrix -  (Copy the matrix)  This function copies the first given matrix into the 
second.  If the sizes are incompatible, it returns false and the copy isn't made.

Get_From_Matrix -  This function looks at the specified location in the given matrix 
and returns the value that it holds.

Add_Matrices -  This function attempts to add the two supplied matrices and return 
the results in the third.  It returns false if it fails for any reason.

Subtract_Matrices -  This function attempts to subtract the second matrix from the 
first and return the results in the third.  If it fails, it returns false.

Multiply_Matrices -  This function attempts to produce a product of the two given 
matrices in the third.  It returns false if it fails for any reason.

Multiply_With_Matrix -  This function attempts to multiply a matrix with a scalar val
ue. It returns false if it fails.

Transpose_Matrix -  This function attempts to transpose a matrix.  This means, it 
tries to flip it on it's side, somewhat.  It returns false if it fails for any reason.

Determinate_Slow -  This function calculates the determinate of the given matrix us
ing the slower but less risky method.

Determinate_Fast -  This function calculates the determinate of the given matrix us
ing the faster but more risky method.

Chapter 17

The Menu unit

Version 5.25

        The Menu unit holds a collection of routines that create choice menus on the screen for 
your programs to use.  There are two different types of menus defined in this unit, Box 
menus (Borland Style) and Bar menus (Lotus Style).  Bar menu's are usually placed upon the 
top and bottom of the screen, while Box menus usually pop up beneath a bar menu or some
where near the center of the screen.
        The Menu unit includes a variety of routines useful to creating menus of your own de
sign.  The unit is specially designed to allow your program to create it's  menus at run time, 
not at compiling time or somewhere in between.  This is highly desirable, because your 
menus can fluctuate depending upon the available options at the time.  And the menus can 
dynamically grow and shrink as you want them to. (Highly desirable for disk file access 
menus)
        Menu is designed to work well with both of the windowing units included, but also was 
designed to operate alone.  The box menu structure features dynamic linking as a doubly 
linked list and is coded to require as little memory as necessary.  Take care to remember to 
deallocate your menus when you're done with them or you'll accumulate a lot of lost space.

How does it work?

        The Box menu system works as a doubly linked list structure of variable records.  The 
menu structure is initialized and then various menu choices are inserted into it either through 
the top or the bottom.  Then the menu routine is called which displays the menu on the 
screen and allows the user to rummage through it until he or she finds the desired choice.
        When the choice is found, the user presses enter and the routine ends, returning the num
ber code corresponding to the choice to the program.  When the menu is not to be used any
more, it's the program's responsibility to tell the unit to disassemble the menu structure.
        This unit will automatically link with the Window or Multiple unit if they are used by the 
program.  This unit will automatically link with the Lock and Pointer units if either is used 
by the program.
        This unit depends on the CRT unit and uses the Core and KeyBoard unit.

Are there any limitations?

        The box menu portion of this unit is limited by the amount of memory available to the 
system and to a maximum of 32 thousand choices.  Box menus of enormous size are possi
ble, with the restriction that each choice line doesn't exceed the size of the Pascal String val
ue.  Take note that the larger the menu, the longer it will take to work through it.  The menu 
screen size is determined by the current CRT window.
        The Bar menu portion of this unit is limited to the amount of  data a string value can hold 
as that's how the menu is passed to the unit.  Also note that there is a maximum amount of 
menu choice items for a bar menu determined by the Max_ Bar_Choices constant.  Note that 
the way the routine differentiates between each choice in the string is the inclusion of a dou
ble space position.  

How to use

        The Menu unit is simple to use in your program.  For bar menus, the actual use amounts 
to no more than two lines of instructions needed in your program, while for the box menu, 
there is more necessary to build the menu structure.  Here's example code to show you how 
to use the unit in your program.  
        First you must tell the compiler that your program uses the Menu unit.  You simply add 
the uses clause at the beginning of your program.

  Uses
    Menu;

        Next you must define the data structure to hold the menu.  This is fairly simple.  You 
simply define a variable of the Bar or Box menu type.  Here's an example of both and data 
variables to hold the results.

  Var
    Bar_Menu_Result: Byte;
    Bar_Menu: Bar_Menu_Type;
    Box_Menu_Result: Word;
    Box_Menu: Box_Menu_Type;

        Somewhere in your code section you initialize the bar menu structure and supply it with 
a string value that defines the choices. The choices you define must be separated from each 
other by two spaces.  A single space only separates two words of a single choice.  The next 
line actually calls the menu routine and allows the user to access the menu.  Bar menu's don't 
have to be deallocated.
 
  Begin
    ...
    Initialize_Bar_Menu( Bar_Menu, '  Choice 1  Choice 2  ' );
    Offer_Bar_Menu( Bar_Menu, Bar_Menu_Result );
    { Bar_Menu_Result now has the choice of the user.  Either 1 or 2 }

        Here is how you define a box menu.  The box menu is first initialized and then is build 
by successive inserts either at the top or at the bottom.  Note the choice descriptions are en
tered as strings, with accompanying word code values, necessary to distinguish between the 
choices.  You may give any number of choices the same code number, but then it may be 
difficult to tell which choice was selected.  A value of zero is returned when escape is 
pressed.

    ...
    Initialize_Box_Menu( Box_Menu );
    Okay := Insert_Top_Box_Menu( Box_Menu, 'Choice 1 ', 1 );
    Okay := Insert_Bottom_Box_Menu( Box_Menu, 'Choice 2 ', 2 );
    ...

        Here we actually call the menu routine, giving the user the menu to select a choice from.  
Note that the routine requires a variable in which to put the result in, otherwise there 
wouldn't be any way to know which choice was selected.  Also notice the last line disposes 
of the box menu.

    ...
    Offer_Box_Menu( Box_Menu, Box_Menu_Result );
    { Box_Menu_Result now has the choice of the user.  Either X or Y }
    Dispose_Box_Menu( Box_Menu );
    ...
  End.

Which compilers are supported?

        The Menu unit was designed to operate with Turbo Pascal  (R) 4.0 through 6.0 and 
Speed Pascal/2 version 1.5.  Please note that the status line is not supported with Turbo 
Pascal (R) version 4.0.

Constants

Max_Bar_Choices - This constant defines the maximum possible choices for the bar 
menu.

Up_Key -  This constant defines a key code that causes the bar menu routine to exit.

Down_Key - This constant defines a key code that causes the bar menu routine to 
exit.
 
Left_Key -  This constant defines a key code that optionally causes the box menu 
routine to exit.

Right_Key -  This constant defines a key code that optionally causes the box menu 
routine to exit.

Enter_Key -  This constant defines a key code that causes the menu routine to exit 
with a choice having been made.

Escape_Key - This constant defines a key code that causes the menu routine to exit 
with a choice having not been made.

Insert_Key -  This constant defines a key code that causes the menu routine to exit 
with a optional choice having been decided upon.  Such as insert a new choice.

Delete_Key -  This constant defines a key code that causes the menu routine to exit 
with an optional choice having been made.  Such as delete the chosen record.

Move_Windows -  This switch allows the top window to be moved around the screen 
using standard keystrokes when set to true.

Lock_System -  This switch allows the system locking routine to be invoked from 
within the menu when set to true.

Normal_Color -  This switch defines the default color of the normal menu text.

Selector_Color -  This switch defines the default color of the selected menu choice 
text.

First_Character_Color -  This switch defines the default color of the first character of 
a menu choice.  This displays the speed search letter.

Leave_Selection_On -  This switch determines if the menu routine will leave the se
lection highlighted after it exits or not.

Sensitive_Mode -  This switch allows the menu to exit as soon as a character choice 
is made instead of waiting for a confirmation by the enter key.

Blend_Attribute -  This switch allows the system to blend the current screen at
tributes with the default attributes for the characters if set to true.

Exit_On_Arrows -  This switch allows the menu system routine to exit when arrows 
are pressed contrary to the menu display.

Highlight_Letter -  This switch causes the box menu routine to highlight the first 
character of the choices when set to true.

Types

Bar_Menu_Type -  This type is defined so that your program may allocate it for use 
with the bar menu routines.  It's best to use the initialization routine to set up this 
data structure.

Box_Menu_Type -  This type is defined so that your program may allocate it for use 
with the box menu routines.  Again, please leave it's initialization to the included 
routine.
  
Variables

Command -  This variable holds the last command value code used by the menu of
fering routines.

Help_Screen - This variable procedure is defined (Not with Turbo Pascal (R) version 
4.0) to allow an optional program supplied procedure to be called whenever the 
help (F1) key is pressed.  The current choice is supplied to the routine.

Display_Status -  This variable procedure is defined (Not with Turbo Pascal (R) ver
sion 4.0) to allow an optional program supplied procedure to be called whenever 
a new choice is highlighted for the purpose of displaying a appropriate status line 
with it.  The current selection is supplied to the routine. 

Procedures
 
Initialize_Box_Menu -  (Initialize the box menu)  This procedure initializes the values 
of the box menu and must be called you add any item to it.  Be sure to use this 
routine before supplying the menu structure to the offering routine.

Dispose_Box_Menu - (Dispose of the box menu)  This procedure disposes of all of 
the memory used by the box menu and returns it to the system.  It then reinitializ
es the menu.

Remove_Top_Box_Menu - (Remove top choice from the box menu)  This procedure 
removes the first choice value from the box menu.

Remove_Bottom_Box_Menu - (Remove bottom choice from the box menu)  This 
procedure removes the last choice value from the box menu.
  
Offer_Box_Menu - (Offer the box menu)  This is the main procedure which offers the 
user the opportunity to make a choice from the box menu.

Initialize_Bar Menu - (Initialize the bar menu)  This procedure initializes the given 
bar menu data structure for use by the program.  Be sure to use this routine be
fore supplying the menu structure to the offering routine.

Offer_Bar_Menu - (Offer the bar menu)  This is the main procedure which offers the 
user the opportunity to make a selection from the bar menu.

Offer_Bar_Menu_Update -  This is a main procedure like Offer_Bar_Menu that of
fers the user the opportunity to make a selection from the bar menu.  Unlike the 
other, though, this routine accepts and performs a precommand.

Functions

Insert_Top_Box_Menu - (Insert choice on top of box menu)  This function accepts 
the choice parameters and puts the appropriate menu option in the box menu at 
the top.  False is returned if it fails. (Usually not enough memory)

Insert_Bottom_Box_Menu - (Insert choice on bottom of box menu)  This function 
accepts the choice parameters and puts the appropriate menu option in the box 
menu at the bottom.  False is returned if it fails.

Insert_Bar_Top_Box_Menu - (Insert bar on top of box menu)  This function, believe 
it or not, puts a bar in the menu on the top.  If it fails, it returns false.  The bar is 
for aesthetic purposes and is ignored by the menu system.

Insert_Bar_Bottom_Box_Menu - (Insert bar on bottom of box menu)  This function 
puts a bar in the menu at the bottom.  If it fails, it returns false.  The bar is for 
aesthetic purposes and is ignored by the menu system.

Get_Top_Box_Menu - (Get from top of box menu)  This function returns the string 
value of the choice at the top of the box menu.

Chapter 18

The Multiple unit

Version 2.3

        The Multiple unit is a unit designed to produce windows on the screen for your program 
use.  Windows are very useful for displaying information that is normally separate from the 
other information on the screen.  Windows are a very popular programming feature and this 
unit supples them for your program to use in any way it needs.
        The Multiple unit has the special feature of being able to manage several overlapping 
windows on the screen simultaneously.  With the supplied routines, the windows are easily 
manipulated directly on the screen in real time.  Windows may be moved, expanded, reduced 
and floated to the top of the pile as well as sunk to the bottom.
        And perhaps best of all, your program doesn't have to worry about keeping the informa
tion in the windows current. (Unlike some other windowing systems)  The information in 
each window is kept internally by the unit in virtual window screens.  By using one of the 
output routines, (Like the standard output file)  the information is intercepted by the Multiple 
unit and put in the virtual window and the screen at the same time.
        Multiple even has the additional versatility of allowing access to all the defined windows 
at the same time, regardless of which one is on top or which one has control at the time.

How does it work?

        The Multiple unit operates by creating virtual windows in memory and intercepting the 
data destined for the CRT unit through the standard input file and redirecting the input to the 
current virtual window.  The other virtual windows may have their own text files or the stan
dard input file may be redirected to them.  All windows are accessed by a handle number.
        As the windows are all in memory, most of the writes to them are invisible, unless the 
window also happens to be displayed on screen.  In that case, special code updates the screen 
to make sure the visible portion of the window reflects what's really there.  If the screen 
window happens to be smaller than the virtual window, only the visible portion is updated.
        A browse routine that handles all the standard movement commands is also included for 
your use to view an entire virtual window.
        The Multiple unit sits on top of the CRT unit and uses the DOS unit also.  The unit 
depends on the Core and KeyBoard units for many of the underlying lower level routines and 
includes code to link up to the other units that support windows.   

Are there any limitations?

        There are several limitations to the Multiple unit.  First and foremost, there is a limit to 
the amount of windows allowed.  This is determined, naturally, by the amount of available 
memory and by MaxWindows and can not exceed 128  which is an awful lot of windows to 
manage at the same time.
        The second limitation is that this unit is completely incompatible with the windows unit.  
But then again, this unit supplies most of the features of that unit anyway, so there really isn't 
any reason to consider using them both anyway.

How to use

        Multiple, while a complex unit is relatively easy to use.  The first thing that your code 
must do in order to use it is to declare the intention to the compiler via the uses clause.  Here 
is example code to display the various routines. 

Uses
  Multiple;

        Next, you have to declare a byte value to hold the handle to the virtual window.  All the 
virtual windows are referred to by this handle and it may possibly be reassigned when you 
wish to float or sink the window.

...
Var
  Window: Byte;
...

        Here in your code, you create a window by calling the Create_Window routine.  Here, I'll 
explain the parameters.  First you define the frame the window will use, then the opening 
animation method.  After these goes the window screen limits by left, top, right and bottom 
corners.  Next you define the attribute of the window, followed by the size of the virtual 
window.
        A value of 0, 0 will make the size of the virtual window defined by the current screen 
coordinates.  Finally, you define if the window is to be visible or invisible. Please note here 
that in this example the animation will be hidden since the window is invisible.

...
Begin;
  ...
  Window := Create_Window( Frame_8, Window_Up_Left, 10, 9, 70, 24,
                           Red_Character + White_Background, 0, 0,
                                   Invisible );
  ...

        Here is the way to make your window appear on the screen if it was initially invisible or 
later changed to invisible.

  ...
  Change_Window_Visibility( Window, Visible );
  ...

        Wasn't that easy?
        Now, see how easy it is to write to your window. The first line shows how to direct the 
standard output file to the window.  It's best, but not always necessary to make sure you are 
using the window you intend to use.  If your code has only one window open, you don't need 
to worry about this step.

  ...
  Switch_Active_Window( Window );
  Write( 'Hello! ' );
  ...

        Now, let's say that you wish to move the window, say perhaps to the right.  You merely 
use the appropriate routine to perform the operation or any other such operation.  Assuming 
Okay is a Boolean variable, here's an example that shows how it's done.

  ...
  Okay := Move_Window_Right( Window );
  ...

        Finally, heres some example code to allow the user to take a good look at what's in the 
window.  First, you float the window, then you use the browse routine.  It's very simple and 
sometimes desirable if the virtual window is larger than the screen representation.  Note that 
the browse routine will make the window visible if it isn't so already.

  ...  
  If Float( Window )
    then
      Browse( Window );
  ...

        At last, when you're done using the window, you close it and release the memory back to 
the system by using the destroy routine.  Not only does this remove the window, but it per
forms a little animation if you wish and the window is visible.

  ...
  Destroy_Window( Window, Window_Up );
  ...
End.

Which compilers are supported?

        The multiple unit was developed to operate with Turbo Pascal (R) compiler version 4.0.  
The additional features were added for use by version 5.0 and the unit has been tested to 
work correctly with compiler version 6.0 as well.  This unit will be updated to work under 
Speed Pascal/2 when the compiler is advanced to handle user defined file devices.  I hope to 
work it so that separate threads may use their own windows.

Constants

Visible -  Constant used to define the current screen status of a window.

Invisible -  Constant used to define the current screen status of a window.

Maximum_Windows -  Constant that defines the maximum amount of windows the 
code will handle.  The value ranges from 1 to 128 since only the first 7 bits are 
used.

????????_Background -  Constants used to specify the background color attribute 
or state of the screen text.  (Black, Blue, Green, Cyan, Red, Magenta, Yellow, 
White)

????????_Character -  Constants used to specify the text color attribute or state of 
the screen text. (Black, Blue, Green, Cyan, Red, Magenta, Brown, Light_Gray, 
Dark_Gray, Light_Blue, Light_Green, Light_Cyan, Light_Red, Light_Magenta, 
Yellow, White, No, Dim_Underlined, Dim, Bright_Underlined, Bright, Re
verse_Video)

Flashing -  Constant used to specify a characteristic of the state of the screen text.  
When used, the text will alternate between appearing and disappearing.

No_Frame -  Constant used to specify no frame.

Frame_1 -  Constant used to specify a frame of single lines all around.

Frame_2 -  Constant used to specify a frame with a double top line.

Frame_3 -  Constant used to specify a frame with a double bottom line.

Frame_4 -  Constant used to specify a frame with a double line on the top and on 
the bottom parts of the frame.

Frame_5 -  Constant used to specify a frame with a double line on the right and on 
the left sides.

Frame_6 -  Constant used to specify a frame with a single line on the bottom of the 
frame.

Frame_7 -  Constant used to specify a frame with a single line on the top of the 
frame.

Frame_8 -  Constant used to specify a frame with double lines all the way around.

Frame_9 -  Same as Frame_1, except with block corners.

Frame_10 -  Same as Frame_2, except with block corners.

Frame_11 -  Same as Frame_3, except with block corners.

Frame_12 -  Same as Frame_4, except with block corners.

Frame_13 -  Same as Frame_5, except with block corners.

Frame_14 -  Same as Frame_6, except with block corners.

Frame_15 -  Same as Frame_7, except with block corners.

Frame_16 -  Same as Frame_8, except with block corners.

Frame_17 -  Constant used to specify a frame with single lines and single inward 
points all the way around.

Frame_18 -  Constant used to specify a frame with double lines and double inward 
points on the top and bottom plus single lines with single inward points on the 
sides.

Frame_19 -  Constant used to specify a frame with single lines and single inward 
points on the top on bottom plus double lines with double inward points on the 
sides.

Frame_20 -  Constant used to specify a frame with double lines and double inward 
points all the way around.

Frame_21 -  Constant used to specify a frame with double lines all the way around 
and double inward points on the top and bottom.

Frame_22 -  Constant used to specify a frame with double lines all the way around 
and single inward points on the top and bottom.

Frame_23 -  Constant used to specify a frame with double lines on the sides and a 
single line on the top and bottom with single inward points.

Frame_24 -  Constant used to specify a frame with double lines on the top and bot
tom with double inward points and single lines on the sides.

Window_Up -  Constant used to specify the window opening and closing animation.

Window_Pop -  Constant used to specify the window opening and closing animation.

Window_Left -  Constant used to specify the window opening and closing animation.

Window_Down -  Constant used to specify the window opening and closing anima
tion.

Window_Right -  Constant used to specify the window opening and closing anima
tion.

Window_Explode -  Constant used to specify the window opening and closing anima
tion.

Window_Up_Left -  Constant used to specify the window opening and closing anima
tion.

Window_Up_Right -  Constant used to specify the window opening and closing ani
mation.

Window_Vertical -  Constant used to specify the window opening and closing anima
tion.

Window_Down_Left -  Constant used to specify the window opening and closing 
animation.

Window_Down_Right -  Constant used to specify the window opening and closing 
animation.

Window_Horizontal -  Constant used to specify the window opening and closing ani
mation.

Window_Vertical_Up -  Constant used to specify the window opening and closing 
animation.

Window_Vertical_Down -  Constant used to specify the window opening and closing 
animation.

Window_Horizontal_Left -  Constant used to specify the window opening and clos
ing animation.

Window_Horizontal_Right -  Constant used to specify the window opening and clos
ing animation.

Delay_Amount -  Variable constant used to specify a delay time for use in window 
animation sequences.

Procedures

Destroy_Window -  This procedure closes and destroys the window from the system.

Browse -  (Browse through the virtual window)  This procedure allows the user to 
browse through the virtual window.  It exits on enter or escape. 

Switch_Active_Window -  (Switch active window to new one)  This procedure reas
signs the default output file to the given window.

Assign_File_To_Window -  (Assign file to specified window)  This procedure binds 
the given file to the specify window.  It works until the file is reassigned or the 
window is destroyed.

ClrEOL - (Clear to end of line)  This procedure clears the given virtual window to the 
end of the current line.

ClrScr -  (Clear Screen)  This procedure clears the given virtual window screen en
tirely.

GotoXY - (Move cursor to X, Y)  This procedure moves the cursor in the given virtual 
window to the given row and column.

Change_Window_Attribute -  This procedure alters the current virtual window at
tribute at the specified location of the given virtual window.

Scroll_Window_Up -  This procedure scrolls the data in the given virtual window in 
the specified direction.

Scroll_Window_Down -  This procedure scrolls the data in the given virtual window 
in the specified direction.

Scroll_Window_Right -  This procedure scrolls the data in the given virtual window in 
the specified direction.

Scroll_Window_Left -  This procedure scrolls the data in the given virtual window in 
the specified direction.

Reposition_Window -  This procedure allows the specified virtual window to be 
moved and resized.  This is slower than the other routines.

Change_Window_Visibility - (Change the virtual window's visibility)  This procedure 
changes the given virtual windows visibility.

Put_TextAttr - (Change the virtual window's attribute)  This procedure changes the 
current attribute of the given virtual window.

Get_TextAttr - (Get the virtual window's attribute)  This procedure returns the current 
attribute of the given virtual window.

Functions

WhereY -  (Where is Y)  This function returns the current cursor row of the cursor in 
the given virtual window.

WhereX -  (Where is X)  This function returns  the current cursor column of the cur
sor in the given virtual window.

Create_Window - (Create a new virtual window)  This function creates a new virtual 
window on the screen and returns a window handle.

Float -  (Float the window)  This function allows the specified virtual window to gain 
the top of the window stack and gives it a new handle number.  If it doesn't work, 
it returns false.

Sink -  (Sink the window)  This function moves the given window to the lowest avail
able value and reassigns the window handle.  It returns false if it doesn't work.

Move_Window_Up - This function moves the given virtual window in the specific di
rection by one character row.  It returns false if it can't complete the operation.

Move_Window_Down -  This function moves the given virtual window in the specific 
direction by one character row.  It returns false if it can't complete the operation.

Move_Window_Left -  This function moves the given virtual window in the specific 
direction by one character column.  It returns false if it can't complete the opera
tion.

Move_Window_Right -  This function moves the given virtual window in the specific 
direction by one character column.  It returns false if it can't complete the opera
tion.

Expand_Window_Up -  This function expands the given virtual window in the specif
ic direction by one character row.  It returns false if it can't complete the opera
tion.

Expand_Window_Down -  This function expands the given virtual window in the 
specific direction by one character row.  It returns false if it can't complete the 
operation.

Expand_Window_Left -  This function expands the given virtual window in the specif
ic direction by one character column.  It returns false if it can't complete the oper
ation.

Expand_Window_Right -  This function expands the given virtual window in the 
specific direction by one character column.  It returns false if it can't complete the 
operation.

Reduce_Window_Up -  This function reduces the given virtual window in the specific 
direction by one character row.  It returns false if the operation can't be complet
ed.

Reduce_Window_Down -  This function reduces the given virtual window in the 
specific direction by one character row.  It returns false if the operation can't be 
completed.

Reduce_Window_Left -  This function reduces the given virtual window in the specif
ic direction by one character column.  It returns false if the operation can't be 
completed.

Reduce_Window_Right -  This function reduces the given virtual window in the spe
cific direction by one character column.  It returns false if the operation can't be 
completed.

Move_View_Left -  This function attempts to move the view in the given virtual win
dow to the left by one character column.  If it can't, it returns false.

Move_View_Right -  This function attempts to move the view in the given virtual 
window to the right by one character column.  It returns false if it can't.

Move_View_Up -  This function attempts to move the view in the given virtual win
dow upwards by one character row.  It returns false if it can't.

Move View_Down -  This function attempts to move the view in the given virtual 
window downwards by one character row.  It returns false if it can't.

Chapter 19

The Music unit

Version 1.1

        The Music unit is a special unit designed to produce music on the computer system using 
it's very own built in speaker.  (Sounds really great, eh?)  The only feature that probably sets 
this unit apart from using Turbo Pascal's own sound routines directly is the way this unit op
erates.
        This unit is designed to accept a group of notes and feed them to the sound routine one 
note at a time in a continuous loop.  Probably the best part of the system is that once the 
notes are entered into the unit, your program really doesn't have to worry about them any
more. (Until the user gets tired of the tune and requests the program to turn it off.)
        Although it looked extremely desirable at first, I refrained from adjusting the computer's 
timing mechanism in this unit.  This makes it fully compatible with all the pop-up utility 
programs and multitasking operating systems out there.  Enjoy.

How does it work?

        This unit operates under DOS by taking over the computer's program linking timing 
interrupt.  The music is placed into a circular queue and is fed continuously into the Turbo 
Pascal sound procedure by the timed interrupt.
        The playing continues in the background, untended for by the program, until the stop 
routine is called.  This clears the queue and sets it up for another note sequence.  The inter
rupt gains control about 18.2 times per second.  This sets the accuracy of the tones timing to 
a little under 1/20 of a second.
        Under OS/2, the system works differently.   A separate thread handles the entire music 
queue enabling the program to work as if the interrupt was still operating.  In OS/2, the 
accuracy of the tone timing is vastly improved.
        The Music unit is designed to be completely automatic in it's operation.  You don't have 
to worry about initializing the interrupt and the system remembers to replace the interrupt 
when it's finished as well.
        The Music unit depends on Turbo Pascal's DOS and CRT units to operate.

Are there any limitations?

        The Music unit is somewhat limited by the constraints of the system.  It only uses the 
system speaker and naturally can only play simple one voice tunes.  An even bigger limita
tion is the timing mechanism which virtually eliminates playing complex music pieces. 
However, for simple purposes, I think you'll like the way it works.

How to use

        I really hope I made the music unit easy to you to use, it's worked well enough for me.  
To use the Music unit in your program, first you must declare your intention to use it to the 
compiler. 

Uses
  Music;

        That's all there is to getting the music system up and running.  Next, somewhere in your 
code, you must add the notes or sounds that you desire to be played to the music system.  
Here's an example.

Begin
  ...
  Add_Note_To_Music( A4, 0.07 );
  ... 
  Add_Sound_To_Music( 900, 1 );
  ...

        Naturally, you're use a lot more notes than this, but you get the picture. When all your 
notes are added to the system, then you can start the music playing.  The music system will 
waits patiently throughout your program until you give it the signal to begin.

  ...
  Start_Music;
  ...

        Now, the music begins playing and your program can do whatever it wants to as the mu
sic is taken care of in the background.  The  music will continue playing either until the pro
gram ends or the Stop_Music routine is encountered.  At that time the sounds cease.

  ...
  Stop_Music;
  ...
End.

        Note that you can start and stop the music as may times in your code as you wish, the 
system doesn't care.  Also note that it's best to stop the music before you add any more musi
cal notes or frequencies to the music queue.

Which compilers are supported?

        The Music unit was designed to compile under Turbo Pascal version 4.0.  It's been tested 
to compile correctly with succeeding versions.  The Music unit has been extended to compile 
under Speed Pascal/2 version Beta 4.

Types

Notes -  This is a user defined type class that defines the musical notes the system 
may work with.  Each note will generate a corresponding frequency on the com
puter's internal speaker.  (C0, CN0, D0, DN0, E0, F0, FN0, G0, GN0, A0, AN0, 
B0, C1, CN1, D1, DN1, E1, F1, FN1, G1, GN1, A1, AN1, B1, C2, CN2, D2, DN2, 
E2, F2, FN2, G2, GN2, A2, AN2, B2, C3, CN3, D3, DN3, E3, F3, FN3, G3, GN3, 
A3, AN3, B3, C4, CN4, D4, DN4, E4, F4, FN4, G4, GN4, A4, AN4, B4, C5, CN5, 
D5, DN5, E5, F5, FN5, G5, GN5, A5, AN5, B5, C6, CN6, D6, DN6, E6, F6, FN6, 
G6, GN6, A6, AN6, B6, C7, CN7, D7, DN7, E7, F7, FN7, G7, GN7, A7, AN7, B7 
& C8 )

Procedures

Add_Note_To_Music - (Add note to music queue)  This procedure adds a prede
fined musical note value to the music system.

Add_Sound_To_Music - (Add sound to music queue)  This procedure adds an unde
fined sound frequency to the music queue.

Clear_Music -  This procedure stops any music that is currently playing and clears 
the music queue entirely.  Then new music may be added or the system stopped.

Start_Music -  This procedure begins playing the music in the music queue.  The 
music begins where it left off.  Opposite of Stop_Music.

Stop_Music -  This procedure ceases the playing of the music in the music queue.  It 
is sort of like lifting the needle of the player and the music will resume where it 
left off.

Chapter 20


The Over unit

Version 1.0

        The Over unit is a simple but hopefully generic unit which I designed to put in my units 
clause before any of the other overlaid units that contain implementation sections.  In 
addition, it gathers all the overlay code that would normally be placed at the beginning of an 
overlaid program into a single unit, thus making it easy to overlay units without having to 
worry about weather you wrote the code correctly or not.
        I really never expected to distribute this one, as it's very simple and basic, but I used it to 
build the TextDemo demonstration program and found it to be inseparable from that 
program.  You may use it if you wish, but I don't expect this one to generate a lot of 
enthusiasm.  Besides, I felt that if I had to included it in the library, even for the sake of one 
simple demonstration program, then it was my duty to touch on it somewhere here.  
Otherwise someone, somewhere would write to me about my lack of foresight.
        Anyway, this unit will load the overlay manager and attempt to load the overlay units 
into the system's expanded memory first, if possible.  If that fails, the unit attempts to 
allocate the largest block of conventional memory necessary or the default maximum size, 
whichever is larger.  And if all this fails, the unit tries to shut down the system.

How does it work

        The Over unit will first load the overlay manager into the system and try to establish a 
work place, either in first expanded memory or conventional memory.  During the steps, the 
status of the unit is displayed on the screen.  The default overlay file is expected to be either 
included at the end of the executable file or is expected to be a file of the same first name as 
the executable file with the .Ovr extension.
        The Over unit uses the Turbo Pascal (R) Overlay unit.  Of course, due to the nature of the 
compilers, this unit will not compile under Turbo Pascal (R) version 4.0 which lacks an 
overlay manager.

Are there any limitations?

        Due to the fact that this unit must operate prior to the program's execution and to the 
execution of it's overlaid brother units, I haven't included provisions to use an overlaid file of 
a different name, yet.  so, in order for this unit to work, the overlay file either must be 
physically appended to the execution file or bear the same name as it.  With the .Ovr 
extension of course.  I thought up a couple ways to expand this unit and perhaps I'll do so 
someday, if enough people express an interest.

How to use

        This unit is very simple to use.  Simply place it in your Turbo Pascal (R) uses clause 
before any of the other units that are to be overlaid.  It will handle the chore of performing 
the initialization of the overlay manager before any of the overlaid units are called.
        Here's an example of how it's to be done.

Program Demonstration( Input, Output );
  Uses
    Over, Windows;
    {$O Windows}
  Begin
    ...
  End.

        Note that this code snipped enables the Windows unit to be overlaid with no further fuss 
on the part of the programmer.  Simply reference the Over unit first, and then be sure to 
inform the compiler that you wish to overlay your specific unit and it's done, automatically.  
Couldn't be easier!
  
Which compilers are supported?

        The Over unit has been determined to compile properly under Turbo Pascal (R) versions 
5.0 through 6.0.  Note that this unit can't work with version 4.0 since it does not support 
overlays.  Sorry about that.

Constants

Minimum_Memory_Allow -  A constant that defines the minimum amount of memory 
by which to use for the overlay buffer.  If a larger buffer is necessary, the code in 
the unit will use that size instead of this one.

Maximum_Overlay_Size -  A constant that defines the default overlay buffer 
increase amount.  The code tries to allocate a buffer of the the largest amount 
plus this constant.

Chapter 21

The PageMaker unit

Version 1.21

        The PageMaker unit was developed originally to allow programs to easily print out pages 
of various types of text on the Epson FX80 compatible printer or any other types of printers 
for that matter, if the corresponding codes were supplied.  The unit accepts text input and 
format it whatever format was desired before it print out the data on the printer.
        Provisions were made for justifying the text, separating the pages and printing headers 
and footers too.  Also one of the goals was to make it easy to write variable output to the 
printer without having to concern oneself with the particulars about the formatting of the data 
and the page sizes.

How does it work?

        The PageMaker unit allocates a block of memory from the heap in which it performs all 
it's work there until it runs out of space to put any more data.  When the page is completely 
full, the data is routed out to the printer and a new page is set up to accept the new data.
        Pages are printed out to the printer on a per page basis.  There is a header defined of five 
lines as well as a footer of the same size.  Adjustable right and left margins are also provided 
to make formatting easier and the output more readable.
        There are other procedures available to your program to help with the formatting of the 
page.  Simply use the procedures to pass along the information to the unit and the unit will 
take care of the rest.
        The PageMaker unit depends on the Printer unit and also uses the library's Core and 
String_Utilities units.

Are there any limitations?

        There are a couple of major limitations to this unit which may reduce the versatility of 
the unit.  First and probably most importantly, is that PageMaker is only set up to work with 
an Epson FX compatible printer. However, in the interest of making this unit more device 
independent and programmable, I've included provisions for setting new printer codes.  Feel 
free to try them out with different printers and seeing how they work.
        Another limitation of this unit, and I'm afraid a major one is it's ability to work only with 
text based printing.  At the beginning, I thought this would only be a minor limitation, but as 
I noted now much memory it took just to support just the text based printing, I realized the 
extent of the amount of memory necessary to support graphics
        The graphic mode alone would take approximately 128 kilobytes per page which is a 
great deal of space to take away from the programming system.  Anyway, graphical ability 
was left out of the system in order to preserve memory space.  Besides, keeping this system 
only text based gives it much more potential to support a lot more of the printers out there.
        Lastly, and perhaps sadly, I couldn't get the PageFile system working under Speed 
Pascal/2.  This will perhaps be corrected for later versions of Speed Pascal/2.  

How to use

        Although I've tried to make this one as easy to use as possible, I'm afraid it wasn't as 
completely successful as the others.  Here's a rundown of the fundamentals for using the 
PageMaker unit.
        First, naturally, you've got to declare to the compiler that you intend to use the 
PageMaker system.  This is done by including the unit name in your Uses clause.  Example..

Uses
  PageMaker

        The PageMaker system allocates it's own memory in it's initialization section as your 
program starts up.  Be forewarned that the code might halt the system if there isn't enough 
memory for the unit to grab off the heap.  Anyway, here's a step by step tutorial on using the 
PageMaker system.
        First, you should clear the current page somewhere in your code.  Although you can 
probably get away without doing this, you might get garbage in your output, so make sure 
you perform this step before sending any data to the system. 

Begin
  ...
  Page_Clear;
  ...

        After the page is cleared, you might wish to set your margins for your printout.  The val
ue you pick for your margins depend a lot on the size of the text you are planning on using.

  ...
  Page_Margins( 5, 5 );
  ...

        Now, if you wish, with all the preliminary work done, you may wish to define the head
ers and footers to use on your printout.  Setting them up is a simple matter of just passing to 
the system what you wish to produce.  Here's some example text that defines a very nice 
looking header.

  ...
  Page_Header1( Centered, Expanded + Heightened, 'John Smith ' );
  Page_Header2( Centered, Regular, '123 Harvard Street ' );
  Page_Header3( Centered, Regular, 'Bay City, Michigan  USA ' );
  ...

        Those are the headers, here are the footers.

  ...
  Page_Footer3( Centered, Subscript, 'Chapter 3 ' );
  Page_Footer4( Centered, Subscript, 'And then there were nine ' );
  ...

        Now that the headers and footers are defined, somewhere, perhaps anywhere in your 
program you have to supply the data to be printed on the page.  That's easily accomplished 
by writing to the PageMaker system with the Page_Write procedures.
        Don't worry about filling up the page.  When the current page is completed, the system 
merely releases it out to the printer and puts the rest of the text at the top of a new one.

  ...
  Page_Write( Regular, Regular, 'Say what?' );
  ...

        Need another way to perform the same output?  Then use the PageFile file output system. 
(Not yet supported of Speed Pascal/2)  Using this method, you can write directly to the 
printer system the same way you would write to a file.  Note that justified printing is not 
supported by this method, since output isn't routed line by line and goes instead character by 
character.  Here is another way to perform the same task as before.

  ...
  PageFile_Attribute := Regular;
  Write( PageFile, 'Say what?' );
  ...

        That's all there is to it.  Now when your last page is completed, remember to flush out the 
rest of the system by using the Page_Print routine.  This should be performed as soon as 
you're all finished so that nothing remains in the PageMaker system.
  
  ...
  Page_Print;
  ...
End.

Which compilers are supported?

        The PageMaker system unit was designed to compile under Turbo Pascal (R) version 4.0. 
 It has been tested and found to compile correctly with versions 5.0 through 6.0.  This unit 
has also been modified to compile under Speed Pascal/2, minus certain features.  

Constants

Pica -  Constant defining a print mode that supports 10 character to the inch.

Elite -  Constant defining a print mode that supports 12 character to the inch.

Italics -  Constant defining a print mode that prints the characters with a distinct slant 
to the right.

Reverse -  Constant defining a print mode that prints the character background for 
an outline, instead of the character itself.

Expanded -  Constant defining a print mode with an increased (Usually doubled) 
character width.

Underline -  Constant defining a print mode that underlines the characters.

Subscript -  Constant defining a print mode that shortens the characters from their 
usual height.

Heightened -  Constant defining a print mode that lengthens the character's height to 
the next line.

Compressed -  Constant defining a print mode that decreases the width of the char
acters.

Emphasized -  Constant defining a print mode that increases the thickness of the 
lines forming the characters.

Superscript -  Constant defining a print mode that shortens the height of the charac
ter and prints it on the top half of the normal line.

DoubleStrike -  Constant defining a print mode that causes the character to be print
ed over itself a second time.

Regular -  Constant which directs the PageMaker system to perform no additional 
formatting to the line.

Centered -  Constant which directs the PageMaker system to adjust the text to be 
centered in the middle of the line.

Justified -  Constant which directs the PageMaker system to adjust the text so that 
it's completely flush with both margins.

Left_Justified -  Constant which directs the PageMaker system to adjust the text so 
that it's flush with the left margin.

Right_Justified -  Constant which directs the PageMaker system to adjust the text so 
that it's flush with the right margin.

Types

Small_String -  A data type used by the system to save memory space and is de
fined for passing the printer initiation codes to the PageMaker system.

Variables

PageFile_Attribute - A word value that defines the current attribute that text written 
through PageFile will be formatted.

PageFile - A text-file variable through which data can be conveniently and easily 
written to the PageMaker system.

Procedures

Set_Up_Printer -  (Set up the printer)  This procedure is designed to accept a new 
set of printer control codes for the PageMaker system.

Page_Clear -  This procedure clears the current page of all the text that was in it.  All 
data that was in the page to be printed out is lost.  The header and footer are 
also cleared.

Page_Margins -  This procedure sets the page margins to the specified values.

Page_Header1 -  This procedure defines what's to appear on the top line of the 
page heading which is printed at the top of every page.

Page_Header2 -  This procedure changes the second line of the page heading.

Page_Header3 -  This procedure alters the third line of the page heading.

Page_Header4 -  This procedure alters the forth line of the page heading.

Page_Header5 -  This procedure alters the bottom line of the page heading.  This 
line should probably be kept blank.

Page_Write -  This procedure allows the given data string to be passed along to the 
PageMaker system.  
 
Page_WriteLn -  This procedure allows the given data string to be passed along to 
the PageMaker system and performs a carriage return after that.

Page_Footer1 -  This procedure defines what is to appear on the top line of the 
page footer which is printed on the bottom of every page.  This line should proba
bly be left blank.

Page_Footer2 -  This procedure defines the second line of the page footer.

Page_Footer3 -  This procedure defines the third or center line of the page footer.

Page_Footer4 -  This procedure defines the forth line of the page footer.

Page_Footer5 -  This procedure defines the bottom line of the page footer.

Page_Print -  This procedure forces the current page to the printer and resets the 
page text for new information.

Page_Reset -  This procedure clears all the data in the current page like 
Page_Clear, but doesn't reset the headers and footers.

Functions

Tab -  This function returns a string of spaces to the given length.

Chapter 22

The Pick unit

Version 2.3

        The Pick unit is a system designed to present to the user the current disk file structure in 
a way so that he or she can select one of the files with which to work with.  The files are 
presented to the user in the form of a box menu so that he or she can easily navigate through 
them and make a selection.
        The system also includes a very easy to use method for changing directories and travel
ing throughout the entire drive system in search of the desired file.  The amount of file names 
is only limited by the amount of heap memory available and the limits of the Menu system.
        In addition, the Pick system allows the removal of the backup files from the file pick list 
and it allows selection of files in the entire tree and not just the current directory.  This new 
version adds the ability to cross drives at the very bottom of the structure. 

How does it work?

        The Pick system uses the library's Menu unit system to construct the menu and offer the 
choices to the user.  The choices are presented in an easy to use form.
        The Pick unit depends on the DOS and CRT units.  It also depends on the library's Menu 
and String_Utilities units for major aspects of it's operation. 

Are there any limitations?

        The Pick system is limited mostly by the amount of heap space that is available when it's 
called and by the amount of choices that the Menu system can support.  

How to use

        The Pick system is small, really only consisting of one function.  To declare to the com
piler that your program intends to use the Pick unit,  remember to put the reference to the 
Pick unit in your programs Uses clause.  For example...

Uses
  Pick;

        Let's assume that a variable called Path exists and it's defined as a string.  The Pick sys
tem would then be invoked somewhere in your code easily as follows.

Begin
  ...
  Path := Pick_File( '' );
  ...
End.

        What's returned in the Path variable is the file name with the path to get to it.  Note the 
use of the empty path name as a parameter.  This causes the Pick system to use the current 
directory as the starting point.  
        Including any other path name would use that path name as the starting point for your 
file pick.  Also note that the system works with the menu system so that if the user presses 
escape for any reason, the routine would be aborted and the file name supplied wouldn't have 
been desired.

Which compilers are supported?

        The Pick unit was designed to compile with Turbo Pascal (R) version 4.0.  It's been test
ed and adjusted to operate properly with versions 5.0 through 6.0 and under Speed Pascal/2 
version 1.5.

Constants

Exclude_Backups -  This variable constant when set to true will force the pick sys
tem to exclude backup files in the choice list. (Files with the .Bak extension)  It's 
default is false.

Allow_Drive_Switch -  This switch when set to true allows the user the ability to 
move across drives.  When set to false the choice is limited to only the current 
drive.  Set to false to operate the system as like previous versions.
 
Variables

Pick_Okay -  This Boolean switch is set by Pick_File as to the result of it's operation. 
 If Pick_File worked, it's set to true, otherwise it's set to false.

Functions

Pick - (Pick file in path)  This function allows the user to search through all the direc
tories starting with the current one in order to select a file to work with.  The path 
is returned in a string format.  It sets the flag to false if there isn't enough memory 
to allocate the pick list.

Chapter 23

The Pointer unit  (Pointer_ for Speed Pascal/2)

Version 1.2

        The Pointer unit is a Pascal interface for the popular pointing devices.  Pointing devices 
such as Mice, TrackBalls, TouchScreens and LightPens have become very popular inputting 
devices for programs and this unit allows you to take advantage of them.
        This unit provides provisions for both direct polling by your program and for indirect 
means through the KeyBoard unit.  The link to the KeyBoard unit is automatically performed 
in the initialization code.  The unit generates keystroke commands whenever the pointer but
tons are activated.
        The unit provides support for single and double clocking with both buttons and includes 
support commands for dragging and dropping.  Pressing down a button will activate the the 
pointer status keys, moving the pointer while holding down a button activates the text 
selection routines.  Double clicking on a button activates special features.

How does it work?

        The Pointer unit operates mostly through the standard pointer device driver interrupts.  
(Interrupt number 33h)   By calling the interrupts, the system polls the pointer device to find 
out where the pointer is and what are the button's status.  The poll is either performed direct
ly by your program,  or the poll is generated automatically by the KeyBoard routine whenev
er your program uses it to poll the keyboard. (Not supported with Turbo Pascal version 4.0)
        The Pointer unit will not operate without an active Pointer driver or if there isn't any 
pointer device.  The system includes code which checks for the existence of the driver and 
doesn't link up to the KeyBoard unit if the driver isn't functioning.
        This unit depends on the DOS and CRT units.  It also uses the library's Core and 
KeyBoard units.
        Under the OS/2 version, the unit makes calls to the operating system and simulates the 
same type of interface as the DOS version.  This makes it easy to compile under both DOS 
and OS/2 without any hassle.

Are there any limitations?

        The Pointer unit has a few limitations, the foremost being that it depends on service from 
the Pointing device driver.  Without the driver, the system will not work, no matter what 
pointer device is attached to the system.  Also make sure the driver is set to support the Mi
crosoft interface.  This unit relies on the Microsoft two button driver to operated effectively.
        Although it's been tested and found to work nicely together with the JoyStick unit, I 
wouldn't recommend using them both in your program.
        When using the pointer in a graphical environment, it's highly recommended that you 
turn off the pointer (Hide it) before anything is written to the screen. (At least in the screen 
area that the pointer resides)  Then be sure to turn the pointer back on when you are finished. 
This also applies to the text mode, but is not as critical in that the pointer doesn't mess up the 
screen as severely.  The KeyBoard interface link defines a special pointer routine which 
handles this case automatically.

How to use

        First and foremost, in order to use the Pointer unit, you must declare your intentions to 
the compiler in your source code.  This is accomplished by using the uses clause and specify
ing the Pointer unit as the system you'd like to use.  Example...

Uses
  Pointer;

or, if you're using Speed Pascal/2 under OS/2 use the alternate unit...

Uses
  Pointer_;

        If you're using one of the units that use the KeyBoard unit, then you're pretty much all 
done.  The unit now supports the Pointer whenever one of the other units is called.  On the 
other hand, if your code doesn't depend on the KeyBoard unit, you have a little more work to 
do.
        Next, If you're going to poll the pointer, you've got to declare a variable to hold the re
sults in.  The Pointer_Data_Type record structure is where the results are returned to you, so 
you must declare a variable of this type to use in your code.  

...
Var
  Pointer_Data: Pointer_Data_Type;
...

        Now, you're ready to use the unit's powerful pointer polling routines. (Whew!  Say that 
three times fast)  This is the easy part.  Most of the work was already taken care of by the 
unit before the program started.  Here's an example of the type of code necessary to set the 
ball rolling.
 
...
Begin
  ...
  Display_Pointer;
  ...

        Now, all there is to do is poll the pointer when you need it.  It's often a good idea to poll 
the pointer at least every second or so.  In this way, the user doesn't get the impression that 
your program has abandoned him or her somewhere off in nowhere or taken a nap or some
thing.  Of course, we realize that this isn't always possible.

  ...
  Repeat { or, perhaps, some other looping mechanism }
    ...
    Read_Pointer( Pointer_Data );
    ... 
  Until Done;
  ...
End.

        See?  That's all there is to it.  Now your program can poll the pointer and use the informa
tion any time you need to.  No fuss or complex routines necessary.  Wasn't that easy?

Which compilers are supported?

        This unit has been written and tested to operate correctly when compiled with Turbo 
Pascal (R) version 5.0.  Currently, it won't compile under Turbo Pascal (R) version 4.0, but it 
should compile correctly with all Turbo Pascal (R) compiler versions later than this.
        The functions of this unit are duplicated in the Pointer_ unit for OS/2.

Constants

Button1_Up -  This variable constant holds the keystroke value the unit returns to 
the KeyBoard unit when the first button of the pointing device is released inside 
the current window.

Button2_Up -  This variable constant holds the keystroke value the unit returns to 
the KeyBoard unit when the second button of the pointing device is released 
inside the current window.

Button1_Down -  This variable constant holds the keystroke value the unit returns to 
the KeyBoard unit when the first button of the pointing device is pressed down 
inside the current window.

Button2_Down -  This variable constant holds the keystroke value the unit returns to 
the KeyBoard unit when the second button of the pointing device is pressed 
down inside the current window.

Button1_Double -  This variable constant holds the keystroke value the unit returns 
to the KeyBoard unit when the first key of the pointing device is clicked twice in a 
timed manner.

Button2_Double -  This variable constant holds the keystroke value the unit returns 
to the KeyBoard unit when the second key of the pointing device is clicked twice 
in a timed manner.

Time_Delay -  This variable constant defines the maximum amount of time in which 
a first click must be followed by a second click to register a double click.  This 
value is a representative of hundredths of a second.

Wait_Time -  This variable constant defines the amount of delay time that is waited 
before sending the command to the KeyBoard unit.  The lower this value, the 
faster the system will work and the more likely it will produce erroneous data en
try commands. 

Types

Pointer_Data_Type -  This record type is defined to pass the information back from 
the pointer polling routine; Read_Pointer.

Variables

Last_Row -  This variable holds the last row location of the current cursor.

Last_Column -  This variable holds the last column location of the current cursor.

Find_Pointer -  This Boolean flag is set to true by the system if the pointer driver was 
detected to be operating.  Otherwise, it's set to false.

Procedures

Read_Position_And_Buttons -  This procedure polls the pointer driver for the current 
X and Y screen coordinates and the current button states.

Display_Pointer -  This procedure makes the pointer visible on the screen.

Hide_Pointer -  This procedure makes the pointer invisible on the screen.

Set_For_Pointer -  This procedure sets up the system for the pointer.

Read_Pointer -  (Read the pointer)  This procedure polls the pointer device driver for 
the status of the pointer and returns the result in the data structure.

Functions

Reset_Pointer -  This function performs a pointer reset and returns the condition of 
the resetting.  If all went well, it returns true, otherwise false.

Check_For_Pointer -  This function checks the system for the pointer device driver.  
If it's there, it returns true.  Otherwise, it returns false.  This is much faster than 
Reset_Pointer.

Chapter 24

The Screen unit

Version 1.0a

        The Screen unit is designed as a simple front end to the user, providing an easy and 
convenient  way to change the P.C.'s video mode from one state to another.  The Screen unit 
was created as an necessity to the DrawDemo program.  It's not very complicated at all and 
is easy to use to switch to any needed graphic mode.

How does it work?

        Basically, the routines use the system's Basic Input/Output System (BIOS) to perform it's 
operations.  When switching to a new video mode, it uses the BIOS to switch modes then 
performs a safety check to ensure the system reflects the mode it's in.  If the BIOS failed to 
switch to the mode, it would be because the hardware doesn't support it at the time.
        The graphic and text modes are defined as follows...
         0 - Text only, 40 characters by 25 lines in 16 shades.
         1 - Text only, 40 characters by 25 lines in 16 colors.
         2 - Text only, 80 characters by 25 lines in 16 shades.
         3 - Text only, 80 characters by 25 lines in 16 colors.
         4 - Graphics, 320 width by 200 height in 4 colors. Text 40x25.
         5 - Graphics, 320 width by 200 height in 4 shades. Text 40x25.
         6 - Graphics, 640 width by 200 height in 2 colors. Text 80x25.
         7 - Text only, 80 character by 25 lines in 2 colors.
         13 - Graphics, 320 width by 200 height in 16 colors. Text 40x25.
         14 - Graphics, 640 width by 200 height in 16 colors. Text 80x25.
         15 - Graphics, 640 width by 350 height in 2 colors. Text 80x25.
         16 - Graphics, 640 width by 350 height in 16 colors. Text 80x25.
         17 - Graphics, 640 width by 480 height in 2 colors. Text 80x25.
         18 - Graphics, 640 width by 480 height in 16 colors. Text 80x25.
         19 - Graphics, 320 width by 200 height in 256 colors. Text 40x25.

        This unit relies on Turbo Pascal's (R) DOS unit to provide the interrupt interface to the 
BIOS.

Are there any limitations?

        The only limitations of the Screen unit are those of the BIOS.  It's fairly simple and not 
prone to very many bugs or errors.  If it fails to alter the video mode, you'll know, either 
directly by checking up on the video system or indirectly by the values it contains for the 
values contained in GetMaxX and GetMaxY

How to use

        Using the Screen unit couldn't be much easier.  First, you simply have to declare to the 
program your intention to use the unit.  This is done, through the uses clause.  Example:

        ...
        Uses
          Screen;
        ...
        
        See, wasn't that easy?  Now all you have to do is use the system to change the video 
mode and the code handles the rest.  In this example we'll change the system to one of the 
lower end graphic modes.  

        ...
        Set_Screen_Mode( 4 );
        ...

        Note that the screen mode numbers are naturally identical to the ones used internally.   
This shows the simplicity of this unit and how directly it ties to the hardware.  In this final 
example, note that the Screen unit provides a utility that clears the screen.  It's fairly common 
to clear the screen in graphical mode by simply resetting the graphic mode.  That's how the 
Screen unit provides this simple service.

        ...
        Clear_Graphic_Screen;
        ...
 
        See, that's all there is.  The Screen unit is very basic and very simple to use.

Which compilers are supported?  

        This unit has been designed and tested to compile and operate correctly under Turbo 
Pascal (R) versions 4.0 through 6.0. 
        
Variables

GetMaxX -  An integer variable that holds the screen width resolution from the last 
screen mode changed with Set_Screen_Mode.
 
GetMaxY -  An integer variable that holds the screen height resolution from the last 
screen mode changed with Set_Screen_Mode.

Screen_Okay -  A Boolean value that reflects the success or failure of the 
Set_Screen_Mode procedure.

Procedures

Get_Screen_Mode -  A procedure that allows the user to poll the BIOS about the 
current screen mode that the system is using.

Set_Screen_Mode -  A procedure that allows the user to specify to the BIOS the 
screen mode that it would like to operate in.   

Clear_Graphic_Screen -  A procedure that allows the user to clear the entire 
graphical screen using the quickest method.

Chapter 25

The Search unit

Version 1.13

        The Search unit is a very small unit containing a few specially designed routines which 
performs searches of the given disk's tree structure for the location of particular files or group of 
files (Given a partial file name).  The unit routines search the entire directory structure and will 
end when either the first match of the supplied file name is found, or when it reaches the end of 
the file tree. (or the drive map.)
        The routines are particularly useful for seeking out the files that support a program when 
they are not in the current system directory.  

How does it work?

        The Search unit 's operation is fairly straightforward.  Using the Turbo Pascal (R) DOS 
unit, they perform file search function calls beginning at the root directory and looking at 
each file and through each directory until the entire structure is exhaustively searched or a 
file or group is found, meeting the desired characteristics.
        This unit relies on Turbo Pascal's (R) DOS unit and upon the libraries String_Utilities 
unit for support.

Are there any limitations?

        With this new implementation, there is only one small limitation of the unit.  If the file is 
found with the specified file name, it can not be absolutely sure that the file is the desired 
one.  It is often possible that the system drives contain several files scattered across it that 
possess the same name.
        Under Speed Pascal/2, there is a problem with some of the locator features which I hope 
to correct later.  Note that Super_Find under OS/2 will generate error windows when 
attempting to read from empty diskette drives.  This may be from the operating system or the 
compiler, I'm not yet sure.

How to use

        The Search unit's use is simplicity itself.  First, like all the other units, you must declare 
your intention to use the Search unit to the compiler by using the uses clause in the appropri
ate part of your program code. (or unit code for that matter) Example:

Uses
  Search;

        Next, let's declare a variable into which the path will be returned. Please note that in or
der to make it easy to use, the Search routines were all designed to use strings for all their 
parameters.

...
Var
  Path: String;
...
  
        Now, it's very easy to invoke the routines of the Search unit.  All you have to do is call 
the functions when you need them in your program.  For example.

Begin
  ...
  Path := Find_Location( '', 'Command.Com' );
  ...
End.

        This function call has the Search function search the entire directory tree structure of the 
current drive for the DOS command processor shell.  If it's successful in finding the file on 
the current drive, then the Path variable will contain a string specifying the entire path need
ed to get to that program from the root directory.  Otherwise it will return an empty string 
that signals that it's failed to find anything.   Here's an other example using super-find.

Begin
  ...
  Path := Super_Find( 'Command.Com', True );
  ...
End.

        In this example, we used super-find which will search out the file across the entire 
system. If this function fails it find a file with the given name on the current drive, it will 
seek out all the other drives either until it finds something that matches or it fails, in which 
case the specified file doesn't exist on the system at all.  See how easy it is to use it?  That's 
all there is to it! 

Which compilers are supported?

        The Search unit has been designed to compile under Turbo Pascal (R) version 4.0.  It's 
also been tested and determined to operate correctly when compiled under versions 5 
through 6.
        This unit has also been recently reworked to compile correctly under Speed Pascal/2 
version 1.5, but is not as completely compatible as of yet.

Functions

Find_Location -  (Find location of file in path)  This function searches all the directo
ries of the given path (the default if none is given) for the first file with the speci
fied name.  When successful the path is returned in a string.

Find_File -  (Find file in the Path)  This function searches all the directories of the 
given path (the default if none is given) for the first file with the specified name.  
When successful, the path and file name is returned in a string.

Super_Find -  This function attempts to perform a super system search for the 
specified file.  A super search first searches the current directory.  If the file is 
found, the result is returned in the string, otherwise it next attempts to search the 
whole current drive.  If that doesn't produce a location for the file, this function 
will then proceed to perform a system wide search across all the available drives.

Super_Find_With_Date -  This function attempts to perform a super system search 
for the specified file and also consider the specified date as a condition of a 
match.  A super search first searches the current directory.  If the file is found, 
the result is returned in the string, otherwise it next attempts to search the whole 
current drive.  If that doesn't produce a location for the file, this function will then 
proceed to perform a system wide search across all the available drives.

Chapter 26

The String_Utilities (Formally String) unit

Version 2.21

        The String_Utilities unit is a loose collection of routines designed to perform various op
erations on the standard Turbo Pascal (R) string structures.  The unit includes routines to 
manipulate strings in various ways and to even perform mathematical operations on numeric 
strings as well.
        Please note that some of the routines in String_Utilities have been enhanced with the use 
of assembly code (compiler versions 6.0 and later) to hasten their processing time.

How does it work?

        Here, I'll explain a little about each group of routines.
        The time and date routines poll the system for the values and then convert the results into 
readable strings for convenient output or use by your program.  The date routines return the 
results in standard North American format but may be easily altered for other areas.
        Write Out Numbers is a routine that converts any integer size value into a readable nu
merical string for your convenience.  Fairly useful for programs that need to write out numer
ical values for things like checks and other security purposes.
        The Remove blank routines are designed to remove all the unwanted  blank characters 
from a string.
        The Spread Out String routines combines both left and right margin justification for the 
convenient use of your programs.  Output is passed to be intercepted by your own routine.
        Comma a String is a nice little routine that performs the service of adding commas, or the 
current country delimiters to a numerical string value for easier reading.
        And finally, there are the arithmetic functions which are designed to perform mathemati
cal functions directly on the numerical strings.
        The String_Utilities unit depends on the standard DOS unit.

Are there any limitations?

        There are a number of limitations that I feel should be discussed here.  The first is that all 
of the routines in this unit are limited to the maximum amount of characters per string, that 
being currently 255 characters.
        The second limitation pertains to the arithmetic routines and is that the Mathematical 
routines do not support scientific exponents.  Also note that the Mathematical routines also 
will perform much more slowly on long strings than on short ones.  Naturally the Multiplica
tion and Division routines will operate much slower than the addition and subtraction rou
tines.

How to use

        The String_Utilities unit, while being composed of many different string handling rou
tines is very flexible and easy to use. The first thing you must do to use the String_Utilities 
unit is to declare to the compiler in your code of your intentions.  This is done by the Uses 
clause.  For example.

Uses
  String_Utilities;

        Next, somewhere in your program code, you must have declare string values so that the 
routine has somewhere to put the results of the functions or procedures you intend to use.  
Assume for this demonstrations that we're defining a couple of general purpose variables.

...
Var
  Numbers1,
  Numbers2: String;
  ...

        Finally, you can use the routines in your code.  Since there are several groups of routines 
offered in the String_Utilities unit, I'll supply a couple of examples of code and explain the 
results.

...
Begin
  ...
  Numbers1 := Write_Out_Number( 2534 );
  ...

        In this example, the string value of the given number is returned to Numbers1.  In this 
case, Numbers1 is defined to be "Two thousand, Five hundred and Thirty Four." 

  ...
  Get_Date( Numbers1 );
  Get_Time( Numbers2 );
  ...

        In this example, the string value of the date and time are returned in Numbers1 and 
Numbers2 respectively.  A possible value for Numbers1 can be "Nine Forty Six AM " and 
for Numbers2 can be "Wednesday, May Tenth, Nineteen hundred and Ninety Five".

  ...
  Numbers1 := Add_Integer_String( '987654321', '123456789' );
  ...

        In this example, the string value returned into Number1 would be "1111111110".

  ...
  Numbers1 := Add_Real_String( '98765.4321', '123.456789' );
  ...

        In this final example, Numbers1 would receive the value "98888.888889"  Recently, this 
unit has been expanded to use the standard country delimiters instead of merely the North 
American format.   Please adjust these examples accordingly and update any code you have 
or compile the unit with the American_Only switch set to true.

Which compilers are supported?

        This unit has been determined to compile properly with Turbo Pascal versions 4.0 
through 6.0.  Note that the use of assembler code is only supported with compiler versions 
greater than 6.0.  Also note that some of the functions are not supported fully with compiler 
version 4.0.  The code has been expanded to compile under Speed Pascal/2 version 1.5.

Constants

American_Only - This switch alters the code generated.  Set to true for compatibility 
with version 1.1 of this unit.

Procedures

Get_Time -  (Get the time)  This procedure takes the time from the system and re
turns it in the form of a readable string.

Get_Date -  (Get the date)  This procedure takes the date from the system and re
turns it in the form of a readable string.

Remove_All_Blanks - (Remove all blanks from string)  This procedure takes a string 
and removes all the space characters (#32) from it.

Remove_Double_Blanks -  (Remove double blanks from string)  This procedure 
takes a string and removes all of the double space character groups from it leav
ing only single spaces.

Spread_Out_String -  (Spread out the string)  This procedure takes a data string and 
even spreads it out to the given size by adding spaces internally. 

Comma_The_String -  This procedure takes a string of numerical form and adds 
commas to it.

Capitalize -  (Capitalize the string)  This procedure takes an alphanumerical string 
and replaces all the small letters with their respective capitals.

Functions

Write_Out_Number -  (Write out the number)  This function takes the given integer 
and returns it's value in the form of a readable string.

Add_Integer_String -  This function takes two numerical integer strings and adds 
them together returning a result in the form of a string.

Subtract_Integer_String -  This function takes two numerical integer strings and 
subtracts the second from the first, returning the result in a string.

Multiply_Integer_String -  This function takes two numerical integer strings and re
turns the product of the two in a numerical integer string.

Divide_Integer_String -  This function takes two numerical integer strings and di
vides the second into the first, returning the result in an integer string.

Mod_Integer_String -  This function takes two numerical integer strings and divides 
the second into the first, returning the remainder as an integer string.

Add_Real_Strings -  This function takes two numerical real strings without expo
nents and returns the sum as a numerical real string.

Subtract_Real_Strings -  This function takes two numerical real strings without expo
nents and returns the difference as a numerical real string.

Multiply_Real_Strings -  This function takes two numerical real strings without expo
nents and returns the product as a numerical real string.

Divide_Real_Strings -  This function takes two numerical real strings without expo
nents and divides the second from the first, returning the result as a numerical 
real string.

Expand -  This function generates a string of the given width with the given charac
ter.

Center -  This function returns an expanded version of the given string so that it fits 
the given width with the original string in the center.

Push_To -  This function returns a Limit sized string composed of the Front and 
Back strings with a number of copies of the Fill character in the center.

Chapter 27

The Structures unit

Version 1.1

        The Structures unit is a memory storage system containing various routines specialized in 
managing some of the more common memory data structures.  In particular, the unit code 
manages stacks, queues and binary trees.
        One of it's greatest advantages is that the code is not built for records of any particular 
size and hence can handle records of all sizes.  (Within the limits of the compiler and the 
code's defined size limit)  And the code is able to handle an almost unlimited amount of dif
ferent structures of each type, so even if you need three stacks, or a hundred, no problem for 
the Structures unit!
        Now, I'll describe a little about each section.  Also note that each section supports the use 
of objects. (Within reasonable limits) 
        The Stack code manages a single linked list in memory with access only to the last 
record put into it.  The stack is accessed via the Push on and Pop off routines and there is 
even an examine routine to retrieve the record off the stack without altering it.
        The Queue code is designed to manage the queue as a doubly linked list in memory.  
Access is only provided to either side of the list.  One side is strictly for insertion while the 
other side is strictly for removal.  An extra examine routine is provided that offers access to 
the top of the queue.
        The Tree code offers the use of a managed balanced binary tree in memory.   This data 
structure is different from the other two in that it requires a key to store the data in a tree 
structure.  Access is provided through a search routine and insertions and deletion routines 
are also available.  Note the tree structure is automatically balanced when records are insert
ed or deleted.

How does it work?

        Each data structure is defined when the corresponding record type is defined in your 
code and initialized using the various create routines.  The defined structures allow the sys
tem to have a unique code record for each data structure in the program.  This allows the 
same code to support as many different data structures of the same type.
        The structures are created and used in a easy manner.  First the data structure must be 
defined in memory.  Then the structure must be initialized and finally filled with data using 
the appropriate routines.  Next, data may be inserted and retrieved from the data structure as 
needed.  Finally, it's good form to deallocate the structure when you're finished using it.  
Routines are included to perform this task for each data structure.
        This unit depends on the Turbo Pascal (R) DOS unit.

Are there any limitations?

        The unit makes no previsions for records of variable length.  All records are assumed to 
be of static length.  Also note that your code should make sure that the variables supplied to 
the routines are large enough to accept all the data or the disastrous risk of overwriting other 
data will occur.

How to use

        Each part of the Structures unit is independent of the other and designed to be as easy to 
use as possible.  First, I'll demonstrate the Stack followed by the Queue and finally the Bina
ry tree sections of this unit.
        The first thing your code must do is declare to the compiler it's intention on using the 
Structures unit.  This is very easy to accomplish using the compiler's built in uses clause.  
        Here's an example. 

Uses
  Structures;

        Next, for the use of the stack, you must declare a variable to hold the stack structure.  
This is easy!  Just declare a stack variable somewhere in your variable declaration section.  
For example.

Var
  Stack: Stack_Type;
  ...

        Now that the stack variable is declared, let's initialize the stack in the code and put 
something in it.  Let's also assume that Data is some kind of variable that holds some kind of 
useful data.  For our purposes, it doesn't really matter what's in it.

...
Begin
  ...
  Create_Stack( Stack, SizeOf( Data ) );
  ...
  Push_On( Stack, Data );
  ...

        Wasn't that easy?  Now, you can put anything you want in the stack.  Just remember that 
the last thing you put on will be the first thing that comes off.   And the second to last thing 
that was put on will be the second thing that gets taken off and so on and so on.  Here we'll 
just take off what we just put on.

  ...
  Pop_Off( Stack, Data );
  ...

        Now that the stack is empty again,  and assuming  out program is near the end, lets dis
card the stack structure.  This should be performed, even if there is nothing in the stack.  
Here's how you do it.

  ...
  Discard_Stack( Stack );
  ...
End.

        Now for the Queue routines.  They're just as easy to use as the stack routines and just as 
versatile.  First, let's declare a variable to hold our queue.

Var
  Queue: Queue_Type;

        Again, lets assume that there is a data record called Data which holds some information, 
again, anything is possible, it really doesn't matter what.  Here, we'll initialize the queue and 
put something in it.

Begin
  ...
  Create_Queue( Queue, SizeOf( Data ) );
  ...
  Put_In( Queue, Data );
  ...

        See!  Wasn't that easy?  Now you can put anything into the queue that you need to store.  
This next example removes the data again from the queue and lastly, like the previous stack 
example, disposes of the queue.

  ...
  Get_out( Queue, Data );
  ...
  Discard_Queue( Queue );
  ...
End.

        That's all there is to it.  Now, lets take a look at the binary tree section of the unit.  The 
binary tree, while an important part of programming, is a little more complicated than using 
Stacks and Queues. First, we'll declare a variable to hold the tree in.  Here I'll also declare a 
more complex record variable that we'll use for the example. 

Var
  Tree: Tree_Type;
  Okay: Boolean;
  Data: Record
          Key: Integer;
          Other_Stuff: Integer;
        End.

        Now that we have some variables to work with, lets create a tree and put in some stuff.

Begin
  ...
  Create_Tree( Tree, SizeOf( Data ), 1 , SizeOf( Key ) );
  ...

        Now let's assume that we've put some data in the Data variable.  Here, we'll insert the 
data into the tree.  

  ...
  Okay := Insert_In_Tree( Tree, Data );
  ...

        Now, depending on the value returned to okay, either we've inserted the data into the 
tree, or nothing happened.  This routine normally only returns false and does nothing when 
we run out of memory. Of course, for our purposes, let's assume that we have a lot of memo
ry and the data goes in properly.  Now, this little bit of code searches the tree for a record 
matching the given data.

  ...
  Okay := Find_In_Tree( Tree, Data );
  ...

        If a record with the same key as data was found in the tree, the data variable is replaced 
with that record and the function returned true to Okay, otherwise it returned false.  Now you 
can search for and retrieve as many records as you wish.

  ...
  Destroy_Tree( Tree );
  ...
End.

        This last bit of code deleted the entire binary tree from memory.  This is always suggest
ed before your program ends.
        That's about all there is to this unit.  For the sake of space, I didn't cover all the available 
functions, but this unit provides a rich assortment for your uses, so enjoy them.  If you wish 
to see a more detained example, by all means, take a good look at the StrcDemo.Pas file in 
the provided demonstration section.

Which compilers are supported?

        This unit has been designed to compiler correctly with Turbo Pascal version 4.0 through 
6.0.  Certain features were added which aren't available with the earliest compiler version.  
This unit has been recently modified so that it can compile and run properly under Speed 
Pascal/2 version Beta 4.

Constants

Maximum_Record_Size -  This constant defines the largest allowable record size.  
This is a practical limit, but may be adjusted in practical circumstances to provide 
a larger size if needed.

Prime_Factor_Default -  This constant defines a best balance value for the tree.

Prime_Factor -  This variable constant defines the current value of the tree balanc
ing factor.  It can range from 2 to 255, but it's offers the best tree balance at a 
lowest value.  Higher values may increase processing speed with the gain lost in 
average search speed.

Types

        Please note that some of unit heading's  record types aren't necessary to understand to use 
the unit and were designed strictly for internal use.  For these reasons, I felt it reasonable to 
skip their definitions in this section.

Stack_Type -  This data structure is used by the stack routines to hold all the infor
mation about the stack.  It's defined so that your program can declare a record of 
it's type for use by the stack managing routines.
 
Queue_Type -  This data structure is used by the queue routines to hold the informa
tion needed to manage the queue.  It's defined so that your program can declare 
a record of this type if it wishes to use the queue managing routines.

Compare_Function -  This variable function (Not supported with compiler version 
4.0) is defined to allow your program to define a replacement compare function if 
you decide it to be necessary.

Tree_Type -  This data structure is used by the binary tree routines to hold the infor
mation pertaining to the binary tree.  It's defined so that your program can de
clare a record of it's type if you wish to use the tree managing routines of the unit.
  
Procedures

Create_Stack -  This procedure prepares the stack record for use.  Note that the 
data record is expected to be the supplied size.

Push_On -  This procedure places a copy of the supplied data in the given variable 
onto a stack record.

Examine_Stack -   This procedure copies the data of the record at the top of the 
stack into the given variable.  

Pop_Off  -  This procedure copies the data of the record at the top of the stack into 
the given variable and discards the top record.

Discard_Stack -  This procedure clears the entire stack of records.  Basically it's like 
reinitializing the stack.

Create_Queue -  This procedure prepares the queue record for use.  Note that the 
data record is expected to match the size that is given.

Put_In -  This procedure places a copy of the given data record variable into the 
bottom of the queue.

Examine_Queue -  This procedure returns a copy of the data stored in the top of the 
queue in the given variable.

Get_Out -  This procedure removes the top element of the queue and returns a copy 
of the data in the given variable.

Discard_Queue -  This procedure removes all the elements of the queue and resets 
it to it's original empty state.

Create_Tree -  This procedure prepares the tree record for use.  Note that the data 
record is expected to match the size that is given.  Also note that the key offset 
must be somewhere inside the size and that the key length must not exceed the 
length of the record.

Destroy_Tree -  This procedure disposes of the entire tree data structure and 
re-initializes it for use.

Change_Key_Routine -  This procedure will substitute your own provided comparing 
routine in place of the default routine.  (Advanced programmers only, Please)  
Also, please note that this feature is supported only through compilers after 4.0.

Functions

Insert_In_Tree -  This function creates a new record with the given data in it and 
places it into the binary tree in the proper location.  It returns false if the operation 
could not be completed.

Update_In_Tree -  This function searches for a record of the old data in the tree and 
replaces it with the new data.  It returns false if anything prevents this from hap
pening.

Delete_From_Tree -  This function removes the record which exactly matches the 
given data from the binary tree structure.  It returns false if the the operation fails.

Find_In_Tree -  This function attempts to find a record with the given key value in 
the binary tree.  If it fails, it returns false.

Find_First_In_Tree -  This function returns the data from the first record of the binary 
tree in logical order.  It returns false if it fails. (the tree is empty)

Find_Next_In_Tree -  This function returns the data from the next record in logical 
order of the binary tree.  It returns false if it fails. (end of the tree structure)

Find_Last_in_Tree -  This function returns the data from the last record of the binary 
tree in logical order.  It returns false if it fails.  (the tree is empty)

Find_Previous_In_Tree -  This function returns the data from the previous record in 
logical order of the binary tree.  It returns false if it fails. (beginning of the tree 
structure)

Get_Absolute_Address -  This function returns the absolute memory address of the 
last accessed record.  (Advanced programming purposes only)

Read_Absolute_Address -  This function returns the data at the absolute address in 
the tree.  See Get_Absolute_Address.

Chapter 28

The Tables unit

Version 1.11

        To tell you the truth, I really don't know why I decided to include this one in the library 
in the first place.   On reflection, I think it was most probably out of guilt.  I won't trouble 
you with the story behind this one, but still, if there is anyone out there who still cares to 
know how I solved it, this was my solution.  Anyway, I really don't think anybody would 
find much use for it, but since I included it in the first release, I decided to leave well enough 
alone and keep it in.
        Tables is simply a unit designed to provide multiple optimal solutions for a given table 
and nothing more.  The table that this unit accepts is a large array of positive integers.  It 
outputs a number of solution arrays depending on how many solution it discovers.  This unit 
incorporates  very simple error checking features.

How does it work?

        As far as I know, there are three methods available to solve such a problem as finding all 
of the optimal solutions to a table.  (For those of you who don't know what this means, find
ing an optimal solution is finding a solution to a table in which the rows represent something 
such as jobs, the columns represent something like available resources and the values in the 
table represents something like the costs.  Finding a solution would entail finding a solution 
that covers all the jobs with all the available resources at the lowest cost possible.)  The 
known solutions are;  The brute force method, (Trying every possible solution and accepting 
the lowest)  The Branch and Bound method, (The fastest, but for some reason, I've never had 
any success at getting this one to perform acceptably) and finally the method that I've used 
here.
        The code in this unit uses a specially modified version of  the Hungarian algorithm to 
find all the possible optimal solutions to the supplied table.  As the algorithm churns through 
the problem, it takes note of any arbitrary choice that must be made.  When a solution is 
generated, it is placed on the solution array.  Then if there was a choice that was made arbi
trarily, the code can restart the algorithm and generate an variant of the previous solution us
ing the other possible choices as the selection. If that's not confusing to you, I don't know 
what is.
        The table is stored in an ANSI file in the given format.  First, the table size is given as an 
integer on the first line.  The table will consist of a two dimensional integer array having the 
size in both dimensions.  Following the size, is the table which consists of the same number 
of lines, each containing the same number of elements in a Pascal readable formation.  Exam
ple:

3
5 6 5 
4 3 1 
5 6 0

        Also note that this solution can be modified to make it very much faster.  However, for 
the sake of simplicity and storage limitations, I've decided to code it as is.

Are there any limitations?

        There are a couple of limitations that I'm sure will become obvious.  The foremost being 
the size of the table.  For this reason, I've included a constant that determines the table size in 
the constant section.  If you find you need to solve tables larger than this, you may modify it 
and recompile the unit.
        The second limitation, is the limit to the values stored in the table.  Note that they are 
originally defined as integers.  Again I figured this necessary to reduce the amount of memo
ry necessary for the unit.  If you wish, you may use long integers or real types, but remember 
that they too will increase the unit's memory requirements.

How to use

        Currently, the Tables unit is available for use only as a report generating facility or for 
direct use by the programmer.  The available routines only work with the Table_Type data 
structure and no provisions are yet offered to fill this structure by any means except through 
a data file.
        Advanced programmers may write their own routines for filling the table and extracting 
the solutions if they so desire.  For a complete demonstration on the use of the Table unit, 
please take a look at the TablDemo.Pas file and it's accompanying data file, Table.Dat.

Which compilers are supported?

        This unit was desired to compile under Turbo Pascal (R) version 4.0.  It has been modi
fied to operate correctly when compiled under versions 5.0 through 6.0.  It's also been 
recently tested and found to compile correctly under Speed Pascal/2 version 1.5.

Constants
 
List_Limit -  This constant defines the maximum amount of solutions that the solu
tion list can handle.  Although some tables may generate far more solutions than 
it can hold, also note that increasing it's size decrease the amount of memory 
available for other uses.

Table_Limit -  This constant defines the maximum size of the table.  This value may 
be increased to allow larger tables, but note that the memory use also increases 
as it get's larger.

Types

Value_Type -  This type defines the type of elements making up the table array.  
Note that it may be altered to use long integers or real numbers if necessary.

Table_Type  - This type defines the table structure which holds the table that the 
code uses.

Solution_Type -  This type defines the structure into which the code stores a single 
generated solution.

Solution_List_Type -  This type defines a structure that holds the list of solutions that 
the code generates.

Procedures

Minimize_Solve_Single -  This procedure generates a single solution for solving the 
given table.  Finds minimal cost.

Minimize_Solve_Multiple -  This procedure generates multiple solutions to solving 
the given table.  Finds minimal cost.

Maximize_Solve_Single -  This procedure generates a single solution for solving the 
given table.  Finds maximum cost.

Maximum_Solve_Multiple -  This procedure generates multiple solutions to solving 
the given table.  Finds maximum cost.

Print_Solution -  (Print out the solution)  This procedure prints out the given solution 
record to the given output file in a report format.

Print_Solutions -  (Print out the list of solutions)  This procedure prints out the given 
solution list to the given output file in a report format.

Read_Table -  (Read in the table)  This procedure reads the table from the given in
put file into the given table structure.

Write_Table -  (Write out the table)  This procedure writes out the table into the 
given text file in the standard formation.

Print_Table -  (Print out the table)  This procedure writes the table from the given ta
ble structure to the given output file.

Chapter 29

TextEdit unit

Version 1.02

        Wow!  I'm here, finally, at the TextEdit unit itself.  This has to, no doubt, be the largest 
unit of the entire library, and the most complex unit I've ever worked on, not to mention all 
the extra support units that go along with it.  Hum, let's see...  What's the best thing to say of 
such a unit?
        The TextEdit unit is designed to implement a full featured and all powerful text editing 
engine for your programming needs.  (That's twice the power of any other text editor you're 
ever likely to find) It's been designed right from the start to provide that versatility and 
function in an easy to use format. (For a full featured text editing engine, that is)
        Take note that this is only an engine, and not as complete as one would like to hope, but 
that's to be expected.  Take my word for it, if it were complete, you wouldn't want it.  You 
wouldn't be able to customize it as much as you'd like to.
        Anyway, I've include a large demonstration program that  should show off most of the 
features of this unit and it's supporting brothers.  Please take a good look at it.  Not only does 
it demonstrate the capabilities, it also includes example substitution routines to show you 
how that's done as well.  Please keep in mind that it's only a demonstration program though.  
What you wish to do with this unit, and believe me there is plenty that you can do, is 
probably beyond that of even the smallest example of that program.
        Anyway, back to the explanation.  The TextEdit unit is only an engine and must therefore 
be fitted properly with a chassis before it can be of any real use.  It has many features that 
can be used or altered or enhanced depending on the purpose you need it for.
        First and foremost, the unit has been designed to handle very large files with almost the 
same amount of ease as the short ones.  This, I feel is very important.  I've seen the mess that 
limited sizes can do to your project.  After having written several novels,  each on a different 
word processing system, I feel I've come to know their limitations all to well.  (Yes, I'm an 
amateur writer as well.  Perhaps I'll even get something published someday)   Believe me, 
nothing more frustrating that having a limit on the size of your file, or even worse on the size 
of a selection block, even if it is DOS that you're working with.
        Anyway, the TextEdit code can handle very large files, up to two million lines of text at 
up to 60 thousand characters per line, provided you have the disk space to accommodate that 
size file and the temporary file it generates. (That's a big IF)
        Second, the TextEdit system is designed to accommodate multiple editing sessions.  Yes, 
that's even a trickier feature, but I made sure to include the support in the code.   Again, the 
amount of  files it can handle at the same time is still limited to a total of two million lines at 
up to 60 thousand characters per line.
        Third, the TextEdit system has been designed to handle very large lines of up to 60 thou
sand characters.  Now, I know that very few people are going to need this feature, but it's 
there, just in case.  I, personally recommend using lines of only 16K in size.   Why?  Because 
the code relies on allocating up to three blocks of the line size limit to perform it's magic.  
Having three blocks of 60 thousand bytes in length is an awful lot of memory to leave as 
leeway.  But, just in case you need it, the capability is there.  I'm not kidding!
        Forth, the TextEdit unit is designed to work in a very compact amount of space.  One of 
my primary goals was to create a text editor system that would be able to operate in the very 
limited area available in the Turbo Pascal (R) IDE debugging session.  And I did succeed.  
Not only does it work completely within the environment, (using overlays of course) but it's 
still able to handle the huge files I hoped to use in it's testing.  (Plus lots of disk buffering)  
How's that for compactness?  
        Fifth, the TextEdit unit has an easy to enhance command system.  In fact, if you're won
dering how to do it, I've included example code in (where else?) the TextDemo.Pas program.
        Sixth, the TextEdit unit has two equally optional units upon which it depends on.  One is 
designed to use the disk (via FileMem) for storing the working data on the disk, and the oth
er is designed to use only memory for that task.  Please note programmers that the memory 
unit will not hold the larger files for editing for obvious reasons.  Still, if you like speed and 
smaller files, the capability is there.
        And Seventh, some command format had to be used for conveying the users wishes to 
the editor engine.  I've decided to use the standard keyboard command combinations. 
(Sometimes referred to as the WordStar (R) command code, with a few alterations.  Why?  
Well, because it was my first word processor, but more importantly, because the Turbo 
Pascal (R) interrogated environment uses it.
        But again, this is not a problem.  It's very easy to change the command formation to any 
other format you wish.  All you have to do in intercept the commands and alter them to the 
editor's formation before they reach the editor command processor itself.  (Sort of like 
creating a translator)  I've included examples of this in my sample program as well.
        Another feature I've included is the background idle time screen updating which I call the 
ripple effect.  It's a feature that I've noticed in one form or another on several word processor 
and editor systems,  and it works nicely on the faster systems.  But for the slower ones, I've 
included an option that turns it off.
        Have you ever though that your system was wasting it's time while it waited for you to 
make a decision about something or other?  Well, I have and that's why I included the back
ground idle time text searching feature.  It actually continues the search for the next available 
word while you're still back there, deciding on what to do with the last one.  It's a feature I've 
often dreamed about, but have never seen on any of the other text editors or word processor 
systems.  Maybe I'm the only person who's even thought of such a feature.  Anyway, try it 
out!  It also is include on the TextCorrect unit.  Oh, and please write and tell me what you 
think about it.  Please, please please!
        Like some of my other units, the TextEdit unit allows you to override the default mes
sage system and include your own routines for your own custom interface.  See the sample in 
my sample program.
        The code in this unit has been designed to conform to some of the other non-standard 
screen sizes it comes up against.  I've worked especially hard to make sure it works well on 
systems that work at other sizes and it's tested to work fine at 128 by 43 lines and 80 by 50 
lines.  Try it out!
        Another feature... Whew!  This unit's just loaded with them!  ...is that there are several 
global flags that alter the performance parameters.  Toggle one of them and the whole system 
works a little bit differently.  Try them out.
        No limits on block sizes.  Too good to be true?  Try it out.  Yes, it takes up a lot more 
memory or disk space, and some transfers can take an awful lot of time to complete, but then 
again, isn't it better to give up a little disk space, memory or speed to give up on the block 
size limitation?
        How about this, instead of locking up the system when the buffer is going to be overload
ed, why not just issue a beeping warning and dump the remaining characters.  It's a lot better 
than having to reboot the system anyway.
        I've taken a lot of pains to make sure this system will recover gracefully form memory 
and disk errors. All you have to do is use the proper HeapError routine and watch it dance. 
(See the example program for a demonstration)
        How about paragraph reforming.  No, this is not a word processor, but I thought it was 
something every text editor should include.  (There is a limitation here, but then there has to 
be)  A paragraph is determined to start at a line and to include any succeeding lines that 
aren't indented. 
        Optional spell checking for a simple text editor!  Am I crazy?   Why not?  Plain text files 
also get spelling errors, don't they?  And it works nicely, too.
        Code's included that supports the pointer system.  The pointer can be used for cursor 
movement, text selection and any thing else you wish to add.
        And there are a great deal more features that are too numerous to mention here.  Look at 
the unit heading for more information.

How does it work?

        Ouch!!  This one I'm going to have to forego for the sake of space.  This sucker is huge 
and I've spend far too much time already just describing it's features.  There's simply too 
much information to put in this document about this unit.  If you're still interested, however, 
then take a good look at the code itself.  There's no better source than that. 
        Here is a list of some of the keystroke commands and their activities.  For a more com
plete listing, please take a look at the unit's header.

[Ctrl]S or the left arrow moves the cursor to the left.
[Ctrl]D or the right arrow moves the cursor to the right.
[Ctrl]E or the up arrow moves the cursor to the preceding line.
[Ctrl]X or the down arrow moves the cursor to the succeeding line.
[Ctrl]A or [Ctrl] left arrow moves the cursor to the preceding word.
[Ctrl]F or [Ctrl] right arrow moves the cursor to the succeeding word.
[Ctrl]QS or [Home] moves the cursor to the beginning of the current line.
[Ctrl]QD or [End] moves the cursor to the ending of the current line.
[Shift][Tab] moves the cursor to the left by tab space amount or one tab stop.
[Ctrl]I or [Tab] moves the cursor to the right by tab space amount or one tab stop.
[Ctrl]W moves the screen up one scroll level.
[Ctrl]Z moves the screen down one scroll level.
[Ctrl]R or [PgUp] moves the cursor up one screen level.
[Ctrl]C or [PgDn] moves the cursor down one screen level.
[Ctrl]QE or [Ctrl][Home] moves the cursor to the top of the screen.
[Ctrl]QX or [Ctrl][End] moves the cursor to the bottom of the screen.
[Ctrl]QR or [Ctrl][PgUp] moves the cursor to the beginning of the file.
[Ctrl]QC or [Ctrl][PgDn] moves the cursor to the ending of the file.
[Ctrl]V or [Ins] toggles the input mode between insert and overwrite.
[Ctrl]N inserts a new line at the current cursor position.
[Ctrl]G or [Del] deletes the character under the cursor.
[Ctrl]Y deletes the current cursor line from the document.
[Ctrl]H or [Backspace] deletes the character to the left of the cursor.
[Ctrl]QY deletes the text to the end of the line.
[Ctrl]T deletes the word to the right of the cursor.
[Ctrl]JL restores the current line to it's original state.
[Ctrl]KB marks the start of a block.
[Ctrl]KK marks the end of a block.
[Ctrl]QB moves the cursor to the top of the block.
[Ctrl]QK moves the cursor to the end of the block.
[Ctrl]KR reads in a block from the file system.
[Ctrl]KW writes out a block to the file system.
[Ctrl]KY or [Ctrl][Del] deletes the entire block from the text.
[Ctrl]P writes out the block to the printer.
[Ctrl]KT marks as a block only the current word.
[Ctrl]H makes the block marking invisible on screen.
[Ctrl]KC copies the marked block to the current cursor location.
[Ctrl]KV moves the marked block to the current cursor location.
[Ctrl]QF starts a find operation.
[Ctrl]QA starts a find and replace operation.
[Ctrl]OL sets the left margin.
[Ctrl]OR sets the right margin.
[Ctrl]L restarts a find or find and replace operation.
[Ctrl]OC centers the current line of text depending on the current margins.
[Ctrl]B or [Ctrl]JO reformats the current paragraph starting at the cursor.
[Ctrl]JQ reformats the whole text file starting at the top.
[Ctrl]JK reformats the whole block starting at it's top.
[Ctrl]OW toggles the auto reform feature.
[Ctrl]J[Space] displays the current location information on the screen momentarily.
[Ctrl]JN allows the user to skip directly to a line by it's number.
[Ctrl]JH or [F1] invokes the help routine.
[Ctrl]P calls up the character menu for inputting special characters.
[Ctrl]JP writes out the entire text to the printer.
[Esc] allows the user to leave the editor.

        This unit uses Turbo Pascal's (R) CRT unit and relies on the following units from the 
PPTool-Kit library; Core, KeyBoard and the String_Utilities unit.
        In addition it has it's own support units consisting of TextLink, TextLine and the 
TextMem or TextFile unit, depending on the compiler directive.

Are there any limitations?

        Sadly, there are a couple of limitations to this unit which I must point out.  The unit, be
ing designed for reliability and performance, does take more processing time than other text 
editors would.  This is not very evident on small files and in fact is barely noticeable, but on 
the larger ones, especially on large block operations, it may take a very long time to com
plete.  For this reason, I've include status screens that display the progress.
        Another limitation is that when reading or writing the file to a disk, the process can take a 
long time with larger files.  Again, this was almost unavoidable because of the way I decided 
to store the system.  The trade-off for the extremely rapid access time across various parts of 
the document was slower initial reading time.
        Please note that other editing systems don't make this as apparent only because they start 
off by reading a small portion of the file and make this available while they continue to read 
the rest of the file into memory in the background where you don't notice it.  But you'll find 
you have to wait for those systems if you decide to skip to the end of the file before the re
mainder of the file has been read in.

How to use

        Whew!  Now this is not an easy task either; describing how to use this unit.  Remember, 
this is only an engine.  It needs a very good frame and it'll probably need a lot of filling in of 
the blanks on your part.  But still, I'll try to give you a little bit of the fundamentals here.
        First, of course, you must declare to the compiler that your code is going to make use of 
the Editor unit.  This is easily done by the Turbo Pascal (R) uses clause.  Also note that since 
TextEdit can, with all it's brother units, be massive in size.  For this reason, it's a very good 
idea to overlay the unit.  But for our demonstration purpose, we'll ignore this fact for the 
moment. (For more information, take a good look at the TextDemo.Pas demonstration pro
gram)  Example.

Uses
  TextEdit;

        Take note that this is going to be a very simplistic demonstration.  Now we've got do de
clare a variable in which to keep all the text data.  This is fairly easy to do.  We'll also de
clare a variable to hold the Boolean results of the calls and a text file to read in the file from 
the disk through. How's this?

Var
  Okay: Boolean;
  The_File: File;
  The_Text: All_Type;

        Now, in the main program we first need to initialize our variables and this is how it's 
done.

Begin
  ...
  Initialize_The_Text( The_Text );
  ...

        Now, wasn't that easy?  Now the variable is ready to hold out text file in it.  In this next 
example, assume that The_File has been opened and we're ready to read in out text for the 
editor system.  It's really easy to do this.

  ...
  Okay := Read_Text_File( The_File, The_Text  );
  ... 

        Now that the file is read into the data structure, to edit it, all we really have to do is pass 
it to the editor function.  Note that this function returns to us a Boolean value that tells us if 
the user altered the data in any way.  If nothing was altered, there really isn't any reason to 
save the data to the file, is there?
  
  ... 
  If Okay
    then
       Edit_Text( The_Text, Okay );
  ...
  
        Now, if Okay is true, the text was altered, otherwise it wasn't.  See how easy it is to do 
this?  But note that this is a very simple example.  If you really wish to make it operate prop
erly, you'd no doubt include some extensions of your own to really rev up the engine, so to 
speak.
        Anyway, assume that we're done with the text and wish to save it.  This is very easy to 
do.  Also assume that The_File is opened for output and ready to go.

  ...
  Okay := Write_Text_File( The_File, The_Text );
  ...

        Now, if  all went well, Okay will be holding the value of true.  On the other hand if 
something went wrong, it'll be false.  Now as a last example, this snipped of code shows you 
how to dispose of the text structure before we're finished.

  ...
  Dispose_Of_Text( The_Text );
  ...
End.

        That's about it.  If you need more information, take a look at the unit's header and the ex
tra special demonstration program that I've include in the tool-kit under the name 
TextDemo.Pas and TDemo2.Pas.  These will give you an extensive example of some of the 
more advanced features that the TextEdit unit is really capable of.

Which compilers are supported?

        This unit compiles under Turbo Pascal (R) version xxx (Should be version 5.0, but I can't 
figure out why it doesn't)  through 6.0.

Definitions

NoMemory -  Compiler directive that when defined includes code that uses the disk 
space to store the file,  When defined as Memory, system memory is used in
stead of the disk.
  
Constants

Normal -  This variable constant defines the normal text display attribute used by the 
unit to write normal text to the screen.

HighLight -  This variable constant defines the highlighted text display attribute used 
by the unit to write blocked text to the screen.

Message_Normal -  This variable constant defines the normal text display attribute 
used by the unit to write normal editor messages to the screen.

Message_HighLight -  This variable constant defines the highlighted text display at
tribute used by the unit to write highlighted editor messages to the screen.

Search_HighLight -  This variable constant defined the showcased text display at
tribute used by the unit to write showcased text to the screen.

Tab_Amount -  This variable constant defines the tab space default amount.  Each 
tab spaces the text by this amount.

Insert_Tab -  This Boolean switch, when set to true, allows the tab key to insert 
spaces, otherwise the tab key only moves the cursor.

Insert_Mode -  This Boolean switch toggles the system between insertions mode 
and overwriting mode.  True puts the system in insert mode.

Space_Right -  This Boolean switch, when set to true, allows the right arrow key to 
add spaces at the end of the line instead of actually reaching the end.

Display_Block -  This Boolean switch, when set to true, allows the marked text to 
appear as such on screen.  When set to false, marked text remains invisible.

Insert_At_EOLn -  This Boolean switch, when set to true, allows extra characters to 
be added at the end of the line.  Otherwise, the line remains at a constant length.

Automatic_Return -  This Boolean switch, when set to true, allows the cursor keys to 
move past the end of the line, otherwise they must remain there or move to the 
next line, depending on the other switches.

Return_Split_Line -  This Boolean switch, when set to true, allows the current line to 
be split when the enter key is pressed.  When set to false, the cursor merely 
moves to the next line.

Delete_Combine_Line -  This Boolean switch, when set to true, allows the delete 
key to combine the next line to the current line when pressed at the end of a line. 
Otherwise, nothing is allowed to happen.

Backspace_Combine_Line -  This Boolean switch, when set to true, allows the 
backspace key to combine the line to the previous line when pressed at the be
ginning of the line.  Otherwise, it does nothing.

Quick_Update_Screen -  This Boolean switch, when set to true, allows the code to 
update the screen in one step instead of doing it in many steps while it's polling 
the keyboard.  (Set to true for slower systems)

Allow_Background_Searching -  This constant, when set to true, includes the spe
cial code that performs the idle time text searching.

Search_Change_All -  This Boolean switch, when set to true, activates the multiple 
search and replace code.  Otherwise, only a single search and replace operation 
is performed.

Search_Selected_Text -  This Boolean switch, when set to true, allows only the se
lected text to be searched in an operation.  Otherwise all text is included.

Start_Search_At_Cursor -  This Boolean switch, when set to true, begins the text 
searching at the current cursor location.  Otherwise the search begins at the top 
of the document or text selection.

Search_Prompt_On_Replace -  This Boolean switch, when set to true, directs the 
search processing engine to prompt the user to make the change.  Otherwise the 
user isn't prompted and the alteration is automatically completed.

Search_Only_Whole_Words -  This Boolean switch, when set to true, directs the 
text searching routines to only identify matches as whole words only.  Instead, 
matches can be obtained from parts of a whole word.

Search_Case_Sensitive -  This Boolean switch, when set to true, directs the text 
searching routines to treat capital and lowercase letters as different.  Otherwise 
the uppercase and lowercase letters are considered identical.

Show_Status -  This Boolean constant, when defined as true, includes special code 
that displays the status of long operations.  Otherwise the status isn't displayed.

Automatic_Paragraph_Reform -  This Boolean switch, when set to true, allows the 
automatic paragraph reforming feature to work.  This shifts words from lines that 
exceed the margin to the next line.  Otherwise lines remain intact.
   
Types

Search_Data_Type -  This structure holds information for the text searching engine.  
It's used to pass information around to the variable searching routines for altera
tion.

All_Type -  This structure holds information to handle the text and cursor.  It's need
ed to pass cursor and screen information to various routines.

Variables

Help -  This variable procedure is called whenever the help key is pressed.  It's pri
mary intended so that you may link a help screen of your own into it, but you may 
replacement it altogether if you wish.  (See the unit's header for more information 
and see the example program to see how to link to it)

Write_Wait -  This variable procedure is called just before a block operation is start
ed.  You may include a replacement for it if you wish.  (See the unit's header for 
more information)

Write_Complete -  This variable procedure is called just after a block operation is 
finished.  You may include a replacement for it if you wish.  (See the unit's head
er for more information)

Write_Search_Failure -  This variable procedure is invoked whenever a search oper
ation fails.  You may include a replacement for it if you wish.  (See the unit's 
header for more information)

Write_Error -  This variable procedure is called whenever an error occurs anywhere 
in the code.  You may include a replacement for it if you wish.  (See the unit's 
header for more information)

Get_Read_File_Name -  This variable procedure is called whenever the unit needs 
to accept the name of a file to read from from the user.  You may include a re
placement for it if you wish.  (See the unit's header for more information)

Get_Write_File_Name -  This variable procedure is called whenever the unit needs 
to accept the name of a file to write to from the user.  You may include a replace
ment for it if you wish.  (See the unit's header for more information)

Get_Search_Data -  This variable procedure is called whenever the unit needs to 
get search data from the user.  It may also prompt the user to alter the various 
search parameters if necessary.  You may include a replacement for it if you 
wish.  (See the unit's header for more information)

Get_Search_And_Replace_Data -  This variable procedure is called whenever the 
unit needs to get search and replace data from the user.  It may also prompt the 
user to alter the various search and replace parameters if necessary.  You may 
include a replacement for it if you wish.  (See the unit's header for more informa
tion)

Get_Confirmation_Of_Change -  This variable function is called to accept input from 
the user about what to do with the current text selection.  It should return a value 
of Y, N or E for escape.  You may include a replacement for it if you wish.  (See 
the unit's header for more information)

Confirm_Changes -  This variable procedure is called after a search and replace 
operation to display a confirmation of the changes performed.  You may include 
a replacement for it if you wish.  (See the unit's header for more information)

Display_Read_Status -  This variable procedure is called periodically to display the 
current status during a read operation.  You may include a replacement for it if 
you wish.  (See the unit's header for more information)

Display_Where_Status -  This variable procedure is called periodically to display the 
location status during a search operation.  You may include a replacement for it if 
you wish.  (See the unit's header for more information)

Display_Write_Status -  This variable procedure is called periodically to display the 
current status during a write operation.  You may include a replacement for it if 
you wish.  (See the unit's header for more information)

Display_Information -  This variable procedure is called to display the information on 
the text file.  You may include a replacement for it if you wish.  (See the unit's 
header for more information)

Get_New_Line -  This variable procedure is called to get the information when the 
user wishes to move directly to a line.  You may include a replacement for it if 
you wish.  (See the unit's header for more information)

Character_Menu -  This variable procedure is called whenever the control P com
mand is pressed to accept an extended character from the user.  The default is 
to display a menu of characters from which the user chooses one of the various 
characters.  You may include a replacement for it if you wish.  (See the unit's 
header for more information)

Escape_Operation -  This variable procedure is called when the escape key is 
pressed during a block operation.  If desired, it can be used to allow the user to 
verify the exit.  You may include a replacement for it if you wish.  (See the unit's 
header for more information)

Function_Key -  This variable procedure is called to allow the substituting of key 
codes for function keys.  You may include a link if you wish.  (See the unit's 
header for more information)

Control_J_Link -  This variable procedure is called to allow additional functions to be 
added to the editor.  You may include a link if you wish.  (See the unit's header 
for more information)

Control_K_Link -  This variable procedure is called to allow additional functions to be 
added to the editor.  You may include a link if you wish.  (See the unit's header 
for more information)

Control_O_Link -  This variable procedure is called to allow additional functions to 
be added to the editor.  You may include a link if you wish.  (See the unit's head
er for more information)

Control_Q_Link -  This variable procedure is called to allow additional functions to 
be added to the editor.  You may include a link if you wish.  (See the unit's head
er for more information)

Other_Buffer -  This variable is available to other external routines of the other units. 
(See the unit header for more information)

Get_Line - This variable procedure is defined for use by the other units that link up 
to the TextEdit system. (See the unit header for more information)

Look_Line -  This variable procedure is defined for use by the other units that link up 
to the TextEdit system. (See the unit header for more information)

Put_Line -  This variable procedure is defined for use by the other units that link up 
to the TextEdit system. (See the unit header for more information)

Swap_Line -  This variable procedure is defined for use by the other units that link 
up to the TextEdit system. (See the unit header for more information)

Working_Buffer -  This variable is available to other external routines of the other 
units. (See the unit header for more information)

Procedures

Dispose_Of_Text -  This procedure releases all the allocated area of the text record 
back to the system and reinitializes the record.

Draw_Screen -  This procedure draws the editing window of the screen for a static 
display.  It's use is of importance to some of the feature units that are designed 
to complement this unit.

Edit_Text -  (Edit the text)  This procedure is the main text editor engine which al
lows the user to edit the text stored in the text record.  (See above for command 
summary)

Initialize_The_Text -  This procedure initializes the text record and the other data 
before the text can be read in.

Confirm_Changes_Default -  This procedure is the default routine called up by the 
Confirm_Changes variable procedure.

Display_Information_Default -  This procedure is the default routine called up by the 
Display_Information variable procedure.

Display_Read_Status_Default -  This procedure is the default routine called up by 
the Display_Read_Status variable procedure.

Display_Where_Status_Default -  This procedure is the default routine called up by 
the Display_Where_Status variable procedure.

Display_Write_Status_Default -  This procedure is the default routine called up by 
the Display_Write_Status variable procedure.

Escape_Operation_Default -  This procedure is the default routine called up by the 
Escape_Operation variable procedure.

Get_File_Name_Default -  This procedure is the default routine called up through 
the Get_File_Name variable procedure.

Get_New_Line_Default -  This procedure is the default routine called up by the 
Get_New_Line variable procedure.

Get_Search_And_Replace_Data_Default -  This procedure is the default routine 
called up through the Get_Search_And_Replace_Data variable procedure.

Get_Search_Data_Default -  This procedure is the default routine called up through 
the Get_Search_Data variable procedure.

Help_Default -  This procedure is the default screen called up through the Help vari
able procedure when the F1 key is pressed.

Write_Complete_Default -  This procedure is the default routine called up through 
the Write_Complete variable procedure.

Write_Error_Default -  This procedure is the default routine called up through the 
Write_Error variable procedure.

Write_Search_Failure_Default -  This procedure is the default routine called up 
through the Write_Search_Failure variable procedure.

Write_Wait_Default -  This procedure is the default routine called up through the 
Write_Wait variable procedure.

Functions

Read_Text_File -  This function reads the text from the file into the working data 
structure.  It returns true only if it's successful.

Write_Text_File -  This function writes the text to the file from the working data 
structure.  It returns true only if it's successful.

Valid_Block_Operation -  This function returns true only if the block is valid and if the 
given point position is not inside the block.

Copy_Block -  (Copy the block)  This function attempts to copy the block marked off 
by the start and finish pointers into the clipboard.  It returns true if it's successful.

Cut_Block -  (Cut the block)  This function attempts to remove the block defined by 
the start and finish pointers into the clipboard.  It returns true if it succeeds.

Paste_Block -  (Paste the block)  This function attempts to paste the block in the 
clipboard into the document at the given location.  It returns true only if it's suc
cessful.

Get_Confirmation_Of_Change_Default -  This function is the default routine called 
by the Get_Confirmation_Of_Change variable function.

Character_Menu_Default -  This function is the default routine called by the Charac
ter_Menu variable function.

Error Codes

400 -  Generated by the unit when for some reason, the new line can't be accepted.

401 -  Generated by the unit when a line can't be deleted.

402 -  Generated by the unit when a new line can't be added.

403 -  Generated by the unit when two lines can't be combined.

404 -  Generated by the unit when a read block operation has failed.

405 -  Generated by the unit when a read block operation obtains an invalid name.

406 -  Generated by the unit when a write block operation has failed.

407 -  Generated by the unit when a copy block operation has failed.

408 -  Generated by the unit when a delete block operation has failed.

409 -  Generated by the unit when a move block operation has failed.

410 -  Generated by the unit when the editor can't accept a new line for any reason.

411 -  Generated by the unit when a printer writing error occurs.

412 -  Generated by the unit when a text writing name is found to be invalid.

Chapter 30

The TextExtras unit

Version 1.0

        The TextExtras unit is a enhancement system for the TextEdit unit.  Not designed as a 
stand alone unit, this one adds several features that were left out of the TextEdit unit includ
ing block manipulation and block sorting features.  Heres a run-down of the enhancements 
that it provides.
        The indent block feature allows the user the option to indent all the lines in the currently 
marked text block, just like the feature in Turbo Pascal (R).  The unindent block feature un
does what the indent block feature does.
        The Flip block feature flips all the lines of the block so that they are in reverse order.  
What's the advantage of this one?  Well, if you sort the block first, then perform this option, 
you've go a list sorted in reverse order.  Also if  you'd like to see your list in reverse order for 
any reason, this is your routine.  Note that if you accidentally flip a block, just repeat the 
operation to return it to the original condition.
        And here's one of my favorites, the Sort block feature.  This function sorts all the lines in 
the block in alphabetical order.  Yes, that's right!  All the lines of a selected block are sorted 
in alphabetical order using the quick sort method.  This is a feature I've greatly missed in 
other text editing systems and a feature I thought should be one of the first to be added.  Note 
that this feature is fast on small block, but will definitely operate slowly on the larger ones.  
(a thousand lines or more)  Also note that this feature may possibly cause a stack overflow 
on blocks larger than half a megabyte.
        Finally, but not least, there's the border feature.  This feature enables you to put a frame 
around the given block.  Yes, you heard that right.  Try out that feature to see how it works. 

How does it work?

        The TextExtra unit links up to the TextEdit unit to provide additional services when it's 
commands are invoked by the user.  The unit wait's patiently until the TextEdit unit passes 
along a keystroke that it doesn't understand.  When this happens, the TextExtra unit wakes 
up and takes a look at what's handed to it.  If it does receive a keystroke that it understands, it 
can then can perform the appropriate operation.
        Here's a list of the keystrokes and the command functions they perform.  Note that some 
of these commands may call up additional menus from which the user must select a addition
al feature.

[Ctrl]KI indents all the lines in the block by one space.
[Ctrl]KU unindents all the lines in the block by one space.
[Ctrl]KF flips all the lines in the block to reverse the order.
[Ctrl]KS sorts all the lines in the block in alphabetical order.
[Ctrl]KZ calls up the routine that puts a frame around the current block.

        Each unit has a different of completing it's operation, so if you'd like more details, take a 
look at the unit's header.
        The TextExtras unit depends on Turbo Pascal's (R) CRT unit.  It also depends on the 
PPTool-kit library; Core, KeyBoard, TextLine, TextEdit, TextLink and the String_Utilities 
unit.

Are there any limitations?

        I don't know of any other, but there is a limitations to the TextExtra unit which I feel I 
should mention.  Note that the Sorting feature works on a recursive quick sorting routine.  
When performing the operation on a vary large block, there is the possibility of overloading 
the stack and causing the program to crash.  For this reason, I recommend making sure your 
program sets aside a generous amount of space for the stack.

How to use

        The TextExtra unit is one of the easiest unit in the library to use.  Depending on the 
changes you'd like to make, it can be as easy as referencing the unit in your uses clause, or as 
defining some routine replacement's for it's functions and assigning them over the variable 
routines.
        To add the features of this unit to your program that uses the TextEdit unit, simply add 
the reference in your code's uses clause.  Example.

Uses
  TextExtras;

        See?  That's all there is to it.  Simple wasn't it?  Anyway, if you wish to (this is optional) 
change the appearance of the user routines, you've allowed to create new routines for the in
terface functions.  See the unit header for more information on this topic.

Which compilers are supported?

        The TextExtra unit was determined to be compatible with with Turbo Pascal (R) version 
5.0 through 6.0.

Constants

Indent_Amount -  This variable constant defines the amount of spaces added by the 
indenting and unindenting routines.  You may alter it if you wish, but it's default 
value of one is probably the best value to use.

Variables

Verify_Sort -  This variable function is invoked before a sort operation allow the user 
to verify that the order destructive sort operation is to be performed.  If it returns 
true, the operation is to proceed. (See unit header for more details)

Get_Frame_Style -  This variable function is invoked before a frame operation takes 
place to allow the user to select the particular frame style to use.  It returns false 
if the user changes his or her mind about the operation.  (See unit header for 
more details)

Error Codes

500 -  This is generated by the unit if for any reason, the indent block feature fails.

501 -  This is generated by the unit for any reason, if the unindent block feature fails.

502 -  This error is generated when the flip block feature fails.

503 -  This error code is generated when the sort block feature fails.

504 -  This error is generated by the unit if the frame feature fails to complete it's 
task.

Chapter 31

The Time unit

Version 1.2

        Although the Time unit was developed primarily as a timing mechanism for testing 
routine speed and performance, it has grown increasingly useful in several of my 
programming projects.  Basically, it's a system front end for accessing the system clock and 
calculating the amount of time passed between two points in a program.  And it's been 
recently updated to allow for time extension of operations.
        The Time unit is designed to determine the amount of time it takes for a certain amount 
of code to complete a process.  The value is returned in seconds into a real number variable 
and even includes a special procedure to eliminate the error by calculating the accuracy ad
justment.

How does it work?

        The time unit goes through the operating system to read the value of the clock at the first 
call and then at the second call.  The difference is then calculated out to determine the 
amount of time that passed between calls.
        When used with the other routine, the system waits until the given amount of time has 
past from the first call to when it receives it.  This is extremely useful in programs that need 
to operate at about the same speed regardless of the system they are operating on.
        This unit depends on the compiler's DOS unit.

Are there any limitations?

        This unit depends on the system clock for it's accuracy.  For most PC compatible comput
ers, the system clock appears to have an accuracy limit at somewhere around 1/20th of a 
second.  On slower processor's this is fairly accurate, but with faster processors, this gives a 
less accurate reading on the relative speed and efficiency of a code segment.
        With a fast processor, you may notice that if some of your code seems to work some
where between 0.00 and 0.05 seconds, you'll get a result of either 0.00, 0.05 or 0.10 seconds. 
This inaccuracy is not the fault of the timing routines in this unit, rather it is the limit of the 
operating system.

How to use

        The Time unit, although mainly a debugging unit, but not necessarily, is very easy to use. 
 First, you must declare to the compiler that your code intends to use the unit.  This is done 
with the program's uses clause.  Example...

Uses
  Time;

        That's all there is to it.  Now, I'll give you a snippet of code that makes use of the unit's 
capability.  Note that in this example the position of the routines and what they are doing.  
For the purpose of this example, assume that there exists a procedure called My_Procedure 
that we wish to time and also assume that there exists a real type variable called Time_Used.

...
Begin
  ...
  Start_Timer;
  My_Procedure( Data );
  Time_Used := End_Timer - Accuracy_Adjustment;
  ...
End.

        Note the placement of the procedure and functions.  This is very important!  End_Timer 
should always be called before Accuracy_Adjustment.  By calling them together in this 
manner, you'll get a very accurate reading of the amount of time it takes to call and perform 
the routine in My_Procedure or any other routine you'd like to substitute for that matter.  
        Here's another snippet of code that demonstrates the other procedure Wait_To.  Note that 
in this example the beginning routine is still Start_Timer, but the ending routine is the 
Wait_To procedure.

...
Begin
  ...
  Start_Timer;
  My_Procedure( Data );
  Wait_To( 1 );
  ...
End.

Again note the placement of the procedures.  In this example, however, the purpose of the 
code is to extend the required time for the procedure.  By sandwiching My_Procedure in 
after Start_Timer and Wait_To, with a value of one second, we are insuring that the whole 
process will take at least one second no matter how fast the system is executing the code.  
This is very useful is slowing down interactive programs such as games and such.
Enjoy!

Which compilers are supported?

        This unit has been determined to compile correctly when compiled with Turbo Pascal (R) 
versions 4.0 through 6.0.  It's been recently modified to use the compiler's calls instead of 
going through the operating system interrupt so that it will compile under Speed Pascal/2 (R).

Procedures

Start_Timer -  This procedure is the first procedure to call to start the timing process. 
 It polls the system for the initial time and stores it.

Wait_To -  This procedure is called after Start_Timer.  It polls the system and waits 
until the time after calling Start_Timer is greater than or equal to the given value.

Functions

End_Timer -  This function is called at the end of the process and returns the 
amount of time that elapsed between when it was called and when Start_Timer 
was called.  The result in seconds is returned as a real number.

Accuracy_Adjustment -  This function returns the amount of time in seconds that it 
takes to perform only the timing routines.  This is added to allow your program to 
eliminate the slight inaccuracy that the timing functions themselves introduce so 
you're program can be more accurate.  This function has most of it's relevance 
for the slowest systems. 

Chapter 32

The Timer unit

Version 1.1

        The Timer unit (Not to be confused with the Time unit)  is a unit that provides a front 
end interface to the operating system's program timer interrupt.  This is useful if your pro
gram wishes to keep it's own count of the time, or wishes to perform some other small but 
useful function at selected intervals.  
        You may specify how many times your procedure will be called up to the system limit of 
eighteen times per second.  Although some of you may not that it is possible to alter this, I 
decided against it to ensure that this unit remains compatibility with virtually all the soft
ware.  Make sure if you do use this unit that your small function uses only re-entrant inter
rupts and code.
 
How does it work?

        The operating system is set up to generate a call to this interrupt once every  0.055 sec
onds.  This unit substitutes it's own interrupt routine in that special program supplied inter
rupt and takes control at each interval second.  At the specified time interval, the routine 
makes a call to your supplied procedure.
        This unit depends on Turbo Pascal's (R) DOS unit to function.

Are there any limitations?

        The use of the interrupt routine within a program calls for careful planning and vital code 
testing.  It's quite possible to crash some operating systems if your routine takes too much 
time to perform any of it's functions. Therefore, it is very crucial that your code take no 
longer than 0.025 (1/40) of a second to perform at maximum.  (Use the time unit if necessary 
to ensure this.  If the code appears to run in less than 0.00 of a second at 80% of the time, it's 
probably fine)
        If your code does take too long to operate, very bad things may happen.  Most likely, 
other system timing routines may be upset and severe errors will result.  Note that some sys
tems must generate timing interrupts to perform the very important tasks of clock updating, 
memory refreshing and operating system disk routines.
        For the aforementioned reasons, I strongly recommend against using any procedures 
which are overlaid.  And by the same token, don't include code that access the disks.
  
How to use

        This unit depends on your program supplying it's own procedure for the operating of the 
routine.  For a simple example of how it operates, I recommend that you study the Pascal 
program in TimeDemo.Pas
        Note that in the program makes use of Turbo Pascal's (R) CRT unit.  When DirectVideo 
is on, this unit doesn't make use of the system's writing routines which aren't re-entrant.  This 
unit may fail to operate properly if used in a graphical mode.
        Also note that the procedure passed to it is of the far call model.  The procedures that you 
pass to the unit must be of the far call model for several reasons.  Note especially that near 
call model procedures will not operate properly with the code in this unit.
        Lastly note that this demonstration program hasn't been tested with some of the multipro
cessing systems that run in the 80x86's real mode.  Hopefully the code should not interfere 
with those type of operating systems.   
 
Which compilers are supported?

        This unit has been written and found to compile correctly with Turbo Pascal (R) version 
5.0.  It's been tested and found to operate properly with version 6.0 as well.

Types

Timed_Procedure -  This is a type defined to make it easy to pass the address of 
your procedure to the initializing procedure.  No parameters are passed.

Variables

Time_Lapse -  This variable is designed to be altered by your program to increase 
or decrease the frequency that the timer routine calls your timed procedure.  This 
value represents 1/18th of a second intervals.

Procedures

End_Timed_Procedure -  This procedure turns off the timed routine system and re
stores the system to it's initial state.  This procedure is automatically called in the 
even the program terminates prematurely.

Begin_Timed_Procedure -  This procedure turns on the timed routine system and 
replaces the system routines.  This procedure should be called only after 
Time_Lapse is set.

Chapter 33

The Windows unit

Version 4.21

        Wow!  Here we are, finally, at the Windows unit.  This unit is perhaps the oldest unit of 
the entire library.  No, I take that back, the second oldest.  This unit alone has taken a lot of 
revision and was split apart from the core unit a long time ago.  Anyway, enough for history, 
now for an explanation of the Windows unit.
        The Windows unit was written to expand upon the features of the standard CRT unit and 
for that matter, only one routine in particular; the window unit. (hence the term windows)  
There probably isn't a programmer around that feels that the standard unit goes far enough, 
and hasn't tried to expand upon the unit or even to totally replace the unit altogether.  I, 
myself, decided to expand upon the unit and this is the result of that effort.
        First of all, let me assure you that this Windows unit doesn't have any connection what so 
ever with that particular graphical based DOS extender from Microsoft (R) that many people 
know and love.  And yes, I've thought about renaming the unit, but then I'd have to go 
through all my code and change the name everywhere. (Whew, that's a job!)  Besides, if I 
had to changed the name of every unit when something comes along with the same name, I'd 
go out of my mind.  Really, I would!
         Anyway, what Windows is is a text based screen management system that does  do win
dows.  Real honest to goodness movable overlapping text based windows and at lightning 
speeds, even on the plain old 4.77MHz 8088.  The only limitation is that you're limited to 
working with the topmost window at the time.  (See Multiple for the other windowing sys
tem)
        Here are some of the things that the Windows unit features;  Extensive error handling 
code that prevents conflicts between various windows.  Minimal memory allocated for each 
window and memory block swapping for resizing and expanding purposes.  Direct communi
cation with the CRT unit provides easy carefree programming.   Special coding makes link
ing with other unit's completely automatic.

How does it work?

        The windows unit creates a stack of windows on the screen, devoting access features to 
the topmost one only.  All features of the previous windows are stored in the stack, but only 
the top one is alterable and remains in effect until it is destroyed by your program.
        Although this may sound rather restrictive, believe me it works quite well.  Although I've 
devised units that support both types of systems, I found this method to work so well, that 
I've often found myself coming back to use this one again and again in my programs.   In any 
case, whichever method you decide to choose, you're covered.
        When ever a window is created on the screen, all the aspects of the previous window 
underlying the location of the new one is preserved.  In this way, the Window routine is de
signed to take over the window routine of the CRT unit. 
        Other features are; the ability to move the window around on the screen, the ability to 
resize the window from it's default size to any other size you wish, the ability to create a vir
tual window of a larger size in the current window frame,  Various animation sequences 
available to open and close your window and  finally that output to the virtual window is 
handled through a special file.
        The Windows unit relies on the CRT and DOS units, and uses the Core and KeyBoard 
units.

Are there any limitations?

        There is one limitation that should be considered.  Although I've successfully used both 
units together in a program, take note that since both units write to the screen, I do not recom
mend using both Windows and Multiple together in the same program.  There is the possibili
ty of them conflicting with each other.
        Speed Pascal/2 currently doesn't support the user defined Text devices files that Turbo 
Pascal does, so I haven't been able to make the Virtual window system operative under that 
compiler.  

 How to use

        The Windows unit is very easy to use in your program.  for the purpose of this explana
tion, I'm only going to cover the basics.  It's very easy to figure out what the rest of the rou
tines do.  Also note that your program does not have to have the same structures at these ex
amples.
        First, your code most tell the compiler that it intends to use the routines available in the 
Windows unit.  This is very easily done by including the uses clause at the very beginning of 
your code before your variables are declared.  Simply add the following piece of code to 
your program and all the window routines are available for your program to use.

...
Uses
  ... 
  Windows;
...

        See, wasn't that easy?  Now for the propose of this example code, open a window.  This 
little piece of code merely opens a window, writes some text to it and closes it again.  Note 
that the Open_Window routine returns a Boolean value as to it's success or failure to work 
properly.

Begin
  ...
  If Open_Window( Frame_1, Window_Pop, 1, 1, 10, 10, Green_Character )
    then
      Begin
        ...
        Close_Window( Window_Pop )
      End;
  ...
End.
 
        This example code opens a 10 by 10 character window in the top left corner of the screen 
and immediately shows it to close it.  Note also that the color of the characters in the window 
are going to be green characters on a black background.  Now let's go a little deeper into 
controlling the looks of that window.  The following code examples could be inserted any
where between the Open_Window and the Close_Window routines are called.

...
Label_Window( Yellow_Character + Green_Background, 'Hello' );
...

        That code simply put a heading on the last opened window that said "Hello".  Note that 
the heading is automatically centered and even truncated if it exceeds the frame width.   This 
next example shows you how to create and write to a virtual window then allow the user to 
use the browse routine to look at what's there.  Assume an open window is displayed on the 
screen.

...
If VW_Create( 15, 25 )
  then
    Begin
      Write( VW, Data );
      VW_Browse;
    End;
... 

        Now wasn't that easy?  This code created a virtual window of 15 by 25 characters, wrote 
whatever was in the variable data into the virtual window and then allowed the user to look 
around at the window just in case all of the window wasn't displayed on the screen.  The 
routine will end only when the enter or escape key is pressed so let's hope that the user 
knows this.

Which compilers are supported?

        This unit was designed to compile correctly with Turbo Pascal (R) version 4.0.  In addi
tion it was expanded to include additional features when compiled with versions 5.0 and later.
The unit has been modified to compile and work somewhat limitedly under Speed Pascal/2.

Constants

??????_Background -  These constants are defined to make it easy to put together 
a valid text attribute color combination by adding one of them together with a 
character value.  Available colors are Black, Blue, Green, Cyan, Red, Magenta, 
Yellow and White.

??????_Character -  These constants are defined to make it easy to put together a 
valid text attribute color combination by adding one of them together with a 
background value.  Available colors are Black, Blue, Green, Cyan, Red, Magen
ta, Brown, Light_Gray, Dark_Gray, Light_Blue, Light_Green, Light_Cyan, 
Light_Red, Light_Magenta, Yellow and White.

Flashing -  This constant is defined to make it easy to put together a valid text at
tribute by adding to a valid character, background combination.

No_Character -  This constant defines a valid text attribute combination for the 
monochrome monitor mode.

Dim_Underlined_Character -  This constant defines a valid text attribute combination 
for the monochrome monitor mode.

Dim_Character -  This constant defines a valid text attribute combination for the 
monochrome monitor mode.

Bright_Underlined_Character -  This constant defines a valid text attribute combina
tion for the monochrome monitor mode.

Bright_Character -  This constant defines a valid text attribute combination for the 
monochrome monitor mode.

Reverse_Video_Character -  This constant defines a valid text attribute combination 
for the monochrome monitor mode.
 
Delay_Amount -  This variable constant defines the amount of time for a single 
movement of window animation.  Increasing it slows the window animation time.

No_Frame -  Constant used to specify no frame.

Frame_1 -  Constant used to specify a frame of single lines all around.

Frame_2 -  Constant used to specify a frame with a double top line.

Frame_3 -  Constant used to specify a frame with a double bottom line.

Frame_4 -  Constant used to specify a frame with a double line on the top and on 
the bottom parts of the frame.

Frame_5 -  Constant used to specify a frame with a double line on the right and on 
the left sides.

Frame_6 -  Constant used to specify a frame with a single line on the bottom of the 
frame.

Frame_7 -  Constant used to specify a frame with a single line on the top of the 
frame.

Frame_8 -  Constant used to specify a frame with double lines all the way around.

Frame_9 -  Same as Frame_1, except with block corners.

Frame_10 -  Same as Frame_2, except with block corners.

Frame_11 -  Same as Frame_3, except with block corners.

Frame_12 -  Same as Frame_4, except with block corners.

Frame_13 -  Same as Frame_5, except with block corners.

Frame_14 -  Same as Frame_6, except with block corners.

Frame_15 -  Same as Frame_7, except with block corners.

Frame_16 -  Same as Frame_8, except with block corners.

Frame_17 -  Constant used to specify a frame with single lines and single inward 
points all the way around.

Frame_18 -  Constant used to specify a frame with double lines and double inward 
points on the top and bottom plus single lines with single inward points on the 
sides.

Frame_19 -  Constant used to specify a frame with single lines and single inward 
points on the top on bottom plus double lines with double inward points on the 
sides.

Frame_20 -  Constant used to specify a frame with double lines and double inward 
points all the way around.

Frame_21 -  Constant used to specify a frame with double lines all the way around 
and double inward points on the top and bottom.

Frame_22 -  Constant used to specify a frame with double lines all the way around 
and single inward points on the top and bottom.

Frame_23 -  Constant used to specify a frame with double lines on the sides and a 
single line on the top and bottom with single inward points.

Frame_24 -  Constant used to specify a frame with double lines on the top and bot
tom with double inward points and single lines on the sides.

Frame_S1 -  Constant which specifies Frame_1 with the addition of a shadow. 

Frame_S2 -  Constant which specifies Frame_2 with the addition of a shadow. 

Frame_S3 -  Constant which specifies Frame_3 with the addition of a shadow. 

Frame_S4 -  Constant which specifies Frame_4 with the addition of a shadow. 

Frame_S5 -  Constant which specifies Frame_5 with the addition of a shadow. 

Frame_S6 -  Constant which specifies Frame_6 with the addition of a shadow. 

Frame_S7 -  Constant which specifies Frame_7 with the addition of a shadow. 

Frame_S8 -  Constant which specifies Frame_8 with the addition of a shadow. 

Frame_S9 -  Constant which specifies Frame_9 with the addition of a shadow. 

Frame_S10 -  Constant which specifies Frame_10 with the addition of a shadow. 

Frame_S11 -  Constant which specifies Frame_11 with the addition of a shadow. 

Frame_S12 -  Constant which specifies Frame_12 with the addition of a shadow. 

Frame_S13 -  Constant which specifies Frame_13 with the addition of a shadow. 

Frame_S14 -  Constant which specifies Frame_14 with the addition of a shadow. 

Frame_S15 -  Constant which specifies Frame_15 with the addition of a shadow. 

Frame_S16 -  Constant which specifies Frame_16 with the addition of a shadow. 

Frame_S17 -  Constant which specifies Frame_17 with the addition of a shadow. 

Frame_S18 -  Constant which specifies Frame_18 with the addition of a shadow. 

Frame_S19 -  Constant which specifies Frame_19 with the addition of a shadow. 

Frame_S20 -  Constant which specifies Frame_20 with the addition of a shadow. 

Frame_S21 -  Constant which specifies Frame_21 with the addition of a shadow. 

Frame_S22 -  Constant which specifies Frame_22 with the addition of a shadow. 

Frame_S23 -  Constant which specifies Frame_23 with the addition of a shadow. 

Frame_S24 -  Constant which specifies Frame_24 with the addition of a shadow. 

Window_?????? -  Constants which define the manner of window opening and 
closing animations.   Up, Down, Left, Right, Pop, Explode, Up_Left, Up_Right,  
Vertical, Down_Left, Down_Right, Horizontal, Vertical_Up, Vertical_Down, Hori
zontal_Left and Horizontal_Right.

Shadow -  This variable constant defines the text attribute color used to create the 
shadow of a window.

Variables

Reverse -  This variable function reverse the high and low parts of a given byte.  It's 
especially useful for switching the text attribute.  (Not supported with compiler 
version 4.0)

VW -  This file allows output to be sent to the virtual window.  It operates exactly like 
the system's output file but shouldn't be redirected.

VW_TextAttr -  This variable defines the current text attribute that the virtual window
ing system uses.  (See Turbo Pascal's (R) TextAttr for an identical example)

Procedures

Assign_VW -  This procedure assigns the given text file to write directly to the virtual 
window.  It operates like the AssignCRT procedure in Turbo Pascal's (R) CRT 
unit.

Close_All_Windows -  This procedure is designed to quickly close all of the open 
windows of the system.

Close_Window -  This procedure closes the current window and resets the system 
to the state before the window was opened.  

Label_Window -  This procedure puts a label on the frame of the current window 
using the supplied attribute.  Labels are only defined on the window, not in 
memory.

VW_Browse -  (Browse through a virtual window)  This procedure allows the user to 
view the contents of the virtual window using the cursor movement keys.  It stops 
when the enter or escape keys are pressed.

VW_ClrEOL -  This procedure offers the same deletion function as Turbo Pascal's 
(R) ClrEOL procedure to the virtual window.  (See ClrEOL)

VW_ClrScr -  This procedure offers the same deletion function as Turbo Pascal's (R) 
ClrScr procedure to the virtual window.  (See ClrScr)

VW_Destroy -  (Destroy window)  This procedure destroys the current virtual win
dow on the stack, leaving only the simple window active.  (See virtual window)

VW_GotoXY -  This procedure offers the same cursor movement function as Turbo 
Pascal's (R) GotoXY procedure to the virtual window.  (See GotoXY)

VW_Scroll_Down -  This procedure scrolls the virtual window downwards.

VW_Scroll_Left -  This procedure scrolls the virtual window leftward.

VW_Scroll_Right -  This procedure scrolls the virtual window rightward.

VW_Scroll_Up -  This procedure scrolls the virtual window upwards.

Functions

Expand_Window_Down -  This function attempts to expand the current window in 
the downwards direction.  It returns false if for any reason it fails.

Expand_Window_Left -  This function attempts to expand the current window in the 
leftward direction.  It returns false if it fails.

Expand_Window_Right -  This function attempts to expand the window in the right
ward direction.  If for any reason it fails, it returns false.

Expand_Window_Up -  This function attempts to expand the current window in the 
upwards direction.  It returns false if for any reason, it can't complete the task.

Move_Window_Up -  This function attempts to move the window upwards on the 
screen.  It returns false it there is no more room to move the window.

Move_Window_Down -  This function attempts to move the current window down
wards on the screen.  It returns false if there isn't any more room to move the 
window.

Move_Window_Left -  This function attempts to move the current window leftward 
on the screen.  It returns false if there isn't any more room.

Move_Window_Right -  This function attempts to move the current window rightward 
on the monitor screen.  It returns false if there isn't any more room to do so.

Open_Window -  (Open a new window)  This function attempts to open a new win
dow on the window stack with the given attributes.  Input and output of the win
dow is still handled directly through Turbo Pascal's (R) CRT unit.  False is re
turned if it fails.

Reduce_Window_Down -  This function attempts to reduce the window from the top. 
 It returns false if it fails.

Reduce_Window_Left -  This function attempts to reduce the size of the current 
window from the left side.  It returns false if it fails.

Reduce_Window_Right -  This function attempts to reduce the window size from the 
right side.  If it fails, it returns false.

Reduce_Window_Up -  This function attempts to reduce the window in the upwards 
direction.  It returns false if it fails.

VW_Create -  (Create a virtual window)  This function attempts to create a virtual 
screen for the current window.  It returns false if it fails.

VW_Move_View_Down -  This function attempts to move the view of the virtual 
screen in the window downwards.  If for any reason it fails, it returns false.

VW_Move_View_Left -  This function attempts to move the view of the virtual screen 
in the window leftward.  It returns false if it fails for any reason.

VW_Move_View_Right -  This function attempts to move the view of the virtual 
screen in the window rightward.  If it fails, it returns false.

VW_Move_View_Up -  This function attempts to move the view of the virtual screen 
in the window upwards.  It returns false if it fails.

VW_WhereX -  This function offers the same cursor location function as Turbo Pas
cal's (R) WhereX function to the virtual window.  (See WhereX)

VW_WhereY -  This function offers the same cursor location function as Turbo Pas
cal's (R) WhereY function to the virtual window.  (See WhereY)

Chapter 34

The Words unit

Version 2.0

        The Words unit holds a word parsing system designed to facilitate the justified printing 
of strings.  It's main purpose is to implement the core routines necessary to justify strings for 
things such as printing them out in an easy to read format.  A variety of justification styles 
are available in this unit for your use.
        If any of this sounds familiar to you, please take note that the same routines are available 
in the PageMaker unit.  In fact, the PageMaker unit is based in part on this unit and so natu
rally combines some of the features available in this unit in it.
        This unit is subject to much improvement without notice.

How does it work?

        The Words unit performs it's work entirely with strings which give it an upward limit of 
255 characters per line.  Although this is more than enough for a text based environment, I 
feel it is somewhat inadequate for the newer graphical based environments which are coming 
around.  Anyway, I guess that's beside the point.  How does this unit work?
        First the routines accept a string of words with which to work with.  The first operation 
performed is the removal of all the multiple blank spaces in the line.  Then the line is split up 
so that no line exceeds the given width.  After this is done, space characters are then added to 
enlarge the line to the specified width if necessary.
        The Words unit depends on the compiler's CRT and DOS unit.  It also relies on the 
String_Utilities unit for a couple string processing routines.

Are there any limitations?

        There are a couple limitations to the Words unit, but then after all, it's really just a small 
support unit anyway. The first and possibly the most critical is that since the unit uses Turbo 
Pascal (R) compatible strings, the code can only process strings up to the maximum string 
length.  This makes for very small paragraphs too.  The second, is that this unit isn't of very 
much use in graphical environments where the width of the letters make all the difference in 
the line justifications.
        Note that the system uses the null character (#0) internally, so that character is the only 
one that shouldn't be used in the strings fed to it.  If necessary, this character is alterable.

How to use

        The Words unit, being simple is very easy to use.  What it does is store up the lines until 
they are ready to be printed out in the justified manner.  To use the Words unit, you simply 
have to declare your intention to the compiler through the uses clause.  Here's an example of 
how that's done.

Uses
  Words;

        Now that your compiler knows what to use in the program.  Let's start doing some justi
fied printing.  Everything else has been done automatically, so all you need to do the justi
fied printing to the screen is shown in this example.

Begin
   ...
  Printout_Justify := Both;
  ...
  Word_Parser_PrintOut( 'Hello!  This example text is going to be '+
                        'printed to the screen in the very narrow '+
                        'width of twenty characters to the line.', 20 );
  ...
End.

        Note that the justification style was adjusted first.  Although this is not necessary, it's de
sirable to do this just in case the current style isn't exactly the one you have in mind.  Also 
notice that the desired text was broken across different lines.

Which compilers are supported?

        This unit has been tested and found to compile correctly under Turbo Pascal (R) versions 
4.0 through 6.0  It also will compile correctly under Speed Pascal/2 version 1.5.

Variables

PrintOut_Justify -  This constant is used by the print out routine to determine the 
current output state of the system.  Possible values are Centered, Right, Left and 
Both which describe the justification styles.

PrintOut -  This variable constant (Only defined with compilers later than 4.0)  allows 
your program to substitute it's own procedure for it to intercept the word parser's 
output.  The default routine will write to the standard output file.

Procedures

Word_Parser_PrintOut -  This procedure accepts the material for the word wrapping 
routines.  It accepts a string of characters which may be broken down into sever
al output lines.

Default_PrintOut -  This procedure is the default output procedure used internally by 
the word justification routines.  It's use is to output the individual lines of the justi
fied output. (See PrintOut)

Chapter 35

The other units

        There are a few other units that I've included in the PPTool-Kit library which I'm sure 
you've noticed haven't been mentioned here or perhaps anywhere in this text.  And there's a 
very good reason,I haven't included them, and now, I'm trying to think one up.
        No, seriously, the few units that haven't been mentioned in this manual are the various 
support units to the main ones which are mentioned here.  And the only reason I haven't 
mentioned them is that I really don't think they need mentioning since they weren't intended 
to be used directly.
        Still, for the sake of completeness, I'll mention them now, but only briefly.  These units 
are the support units upon which the other's depend, sometimes heavily.  Perhaps sometime 
in the future, when I get around to it, I'll include them in this manual, but for now, this will 
have to do.
 
        The TextLine unit holds all the routines needed to handle the TextEdit unit's  text 
lines upon which it and it's brother unit's depend.   Basically, I consider this unit a 
low lying member of the PPTool-Kit library, or if you will, a silent partner.  Still, this 
unit is of special importance in the library for providing services to large string type 
arrays of characters.  For anyone interested, the constant that defines the maximum 
length of the text lines in the TextEdit unit is in TextLine.

        Next is the TextLink unit which provides a familiar circle of routines upon which 
the TextEdit unit and it's brother's communicate.  This unit provides a sort of landing 
platform between the floating capabilities of the TextEdit unit, the TextCorrect unit 
and the TextExtras unit.  You see, in an attempt to conserve memory, I decided to 
allow the other unit's to be overlaid if desired.  It works very well, but there's got to 
be some unit that keeps things on the ground.  Anyway, this unit is it.

        Okay, now it's time to mention the TextMem unit.  This unit implements the text 
storage routines in the systems memory for the TextEdit unit.  That is when the text 
is going to be stored in memory instead of on secondary storage unit.  TextMem will 
provide very fast text movement capabilities but doesn't have the depth of it's broth
er. (See TextFile)

        Now about the TextFile unit.  This unit is the opposite to TextMem and performs 
the exact identical features of it's brother, only it's different.  How's that for confus
ing?  This unit too, implements the text storage routines for the TextEdit unit, only 
this one does it on the system disk.  I guess if that confuses you, think of it like two 
brothers with the same talents who don't get along with each other.  The TextMem 
and the TextFile units may both be used by TextEdit, but not at the same time.  
TextFile provides enormous text storage capabilities, but doesn't have same speed 
of it's brother.


Part II
Beta Section

Chapter 36

Introduction

        This section is a special extension of the Pascal Programming Tool-Kit users manual.  It 
was specifically set aside for the documentation of the beta units that are constantly being 
added to the library.
        First of all, I'll bet some of you are asking yourself at this moment; what exactly is a Beta 
unit?  Well...  I'll tell you.   
        In a nutshell, a beta unit is a programming unit that is not quite ready for any real heavy 
duty work.  It's just at a stage for a sort of preview if you will.  Basically, It's a unit that is in 
the stage of extensive testing.
        Now you're probably wondering why someone like me would decided to include beta 
unit in my library.  It's really quite simple.
        I include Beta units in my library as a sort of preview to upcoming events, as a method of 
gaging the response to some of my projects, as a test of the unit's practicability and 
usefulness, and finally, it's a great way to get others to assist in testing and debugging the 
code.
        Sounds confusing, doesn't it?
        Anyway, the point of this section is to document the beta units separately from the main 
more established collection.  This is not to say that a beta unit isn't firm, only that it's much 
newer and more likely to contain bugs than the others. 

Chapter 37

The ANSI_CRT unit

Version 1.1 - Beta

        The ANSI_CRT unit provides a system of inter-related routines that allow manipulation 
of the text screen and direct control of the cursor using standard ANSI screen commands 
instead of going through the BIOS (Basic Input/Output System) or the operating system.  
The unit is set up to perform somewhat like Turbo Pascal's (R) CRT unit, with the exception 
of lacking the raw input and sound control features.
        The ANSI_CRT unit was originally designed to make text window performance possible 
on dumb ANSI terminals.  It operates by sending escape codes directly to the CRT screen 
driver, instead of passing the information through the operating system.  This slows the 
process considerably and isn't used much for the same reasons, but by creating such a 
system, it does make it possible to control remote screens that recognized ANSI CRT codes.

How does it work?

        First the unit opens the standard system file through which it will produce the output.  
This file is assumed to to be the CRT screen and that the ANSI code driver is assumed to be 
operating through it.  Then the unit redefines the standard output file handle so that output 
will be directed from the program, through the unit and out to the standard system file.
        Internally, the unit allocates a region of memory in which it keeps a duplicate of the data 
that  is sent to the CRT system through the output file.  The unit works by keeping track of 
the entire screen display internally in the data structure and outputting the codes necessary to 
create a CRT display much like the one possible through the operating system routines.
        This unit relies on Turbo Pascal's (R) DOS unit to handle the definition of the file input 
and output routines. It supports windows on the screen in various colors.  Colors supported 
are Black, Blue, Green, Cyan, Red, Magenta, Yellow and White.

Are there any limitations?

        Generally, this unit may cause problems if it is used alongside Turbo Pascal's (R) CRT 
unit since they both (Purposely) employ some of the same procedure and function names 
which is almost certainly going to lead to confusion errors.
        Also note that larger windows will almost always operate much more slowly than small 
ones.  The largest text window that the code allows for is 80 characters across by 25 rows 
down.
        The unit will operate more successfully in the text video modes.  ANSI screen codes do 
not work as well in graphical environments.

How to use

        This unit supports a subset of  Turbo Pascal's (R) CRT unit.  See the CRT unit definitions 
in the users manual.  

Which compilers are supported?  

        This unit has been designed and tested to compile under Turbo Pascal (R) versions 4.0 
through 6.0.  The ANSI screen driver must be present in the CONFIG.SYS file in order for 
this unit to work on the PC's screen.

Variables
  
Wrap - A Boolean variable that alters the ability of the unit to wrap text around to the 
next line when it reaches the end of the screen window.

Screen - This variable holds the current screen data as a two dimensional array of 
characters and attributes.

OutWrite -  This text file is the file through which data is sent out to the ANSI screen 
driver. 

Procedures
        
ClrEOL - (Clear to end of line)  A procedure that clears the text from the current 
cursor position to the end of the current line This procedure only works on the 
current cursor row. 

ClrScr - (Clear screen)  A procedure that clears the current screen window of all text. 
 This procedure also reinitializes the cursor row and position to the normal 
starting point in the upper left hand corner of the window.

DelLine - (Delete line)  This procedure deletes the current cursor line and moves all 
succeeding lines of the current screen window upwards.

GotoXY - (Go to x, y)  This procedure moves the current cursor to the approximate 
coordinates in the current screen window.

HighVideo - (High Video)  This procedure changes the current video attribute to 
produce bright characters on a black background.

InsLine - (Insert Line)  This procedure inserts a line in the current row of the cursor 
and moves the succeeding lines of the current screen window down.

LowVideo - (Low Video)  This procedure changes the current video attribute to 
produce dim characters on a black background.

NormVideo - (Normal Video)  This procedure changes the current video attribute to 
produce bright characters on a black background.

TextBackground - (Text Background)  This procedure changes the background color 
of the current screen window.

TextColor - (Text color)  This procedure changes the text color of the current screen 
window.

TextMode - (Text mode)  This procedure alters the screen text mode.

Window -  This procedure define a text window on the screen.

Assign_ANSI - (Assign file to ANSI screen)  This procedure assigns a text file to 
write to the ANSI unit file handlers.  The result is that the output is routed through 
the unit to the standard output device.

Functions

WhereX - (Where is X)  This function returns the current cursor's column position 
relative to the current screen window.

WhereY - (Where is Y)  This function returns the current cursor's row position 
relative to the current screen window.

Chapter 38

The Frames unit

Version 1.1 - Beta

        Somewhere along the way, I discovered that I needed a routine to draw a fancy frame on 
the screen.  I had thought there would be hundreds of such pieces of code lying about out 
there in programming land, but I couldn't find any; none at all.  It seemed as if everyone else 
had wandering into the camp of interface consistency and I was left alone in the wilderness 
of self creativity alone, lost and forgotten.. There just didn't seem to be any readily available 
routines that would do the job.  So as all good programmers do, I wrote my own.  And here 
they are. 
        Now don't get me wrong here, I don't actually expect everybody to use these routines, not 
when everybody is rallying around the consistent user interface flag.  I'm even wondering 
why I myself have decided to include them in this package.  But then when I reflected back 
on my own long and fruitless search for framing routines way back when, I couldn't help 
thinking that if, by including these routines in this programming tool-kit, maybe, just maybe 
I'll save somebody else from the headaches, the torture and the many other problems that I 
went through trying to find routines such as these.
        This unit is designed to simply draw a variety of different frames on the graphic screen 
using the graphic routines contained in my draw unit. It features quick and efficient code to 
speed the drawing process of frames of any proportions.

How does it work?

        This unit is fairly straightforward in how it works.  There are many support routines that 
make up the bulk of the code.  Several are used to draw each frame.  Several of the units 
depend on the single internal routines, so be careful if you decide to modify the behavior of a 
single frame routine.  Also note that the frames are drawn in a manner that reduces the 
computation portion greatly and for this reason, the frames may appear to be drawing 
themselves in a less than appealing manner. 
        The frames are drawn on the screen at the coordinates provided.  The method and the 
effects are different for each routine, so follow the instructions for each one.  After their 
layout is calculated, the frames are drawn on the screen to the exact specifications.  This 
means that the code will attempt to draw a frame of the given proportions weather they make 
sense or not.   Also note that the frames may not draw on the screen properly if the frame is 
too small.  My advice is to experiment with the frame to determine the results at different 
sizes. 
        This unit relies on the Draw unit for it's drawing routines.

Are there any limitations?

        I really can't think of any limitations to this unit except that the frames will appear to be 
more blocked (muddy) as they get smaller.  Also note that as the resolution increases, the 
line thickness may not be defining enough.  Currently, there is no fix for this except by 
drawing a slightly shifted frame on top.

How to use

        It's very easy to use the Frames unit, simply add the Frames code to your uses clause and 
it's ready to go. 
        Example...

...
Uses
  Frames;
...

        Next, you have to put the screen in graphics mode so that you can draw the frames on the 
screen.  This is easily done using the screen unit.  Here's an example of the code you'd need 
to put the system in graphics mode.  Note that you don't necessarily have to use the Screen 
unit to do this, you may use any other method or code you'd like.

...
Uses
  Screen;
  ...
  Begin
    ...
    Set_Screen_Mode( 6 );
    ...

        Now the system is ready to go.  Simply clear the screen and call upon one of the Frame 
procedures to do it's thing.  They are all fairly simple to use.
        Here's an example drawing a frame on the screen from the top right hand corner to the 
bottom.

        ...
        Draw_Frame1( 0, 0, GetMaxX, GetMaxY, 20, 10 );
        ...

        See that's all there is to it.  For more examples, see the included demonstration file 
FramDemo.Pas and follow it as it goes through it's paces.  Also note that there is no reason 
that a couple frames can't be combined together.  In fact, a few of them were written the way 
there were for just such a purpose.

Which compilers are supported?  

        This unit has been designed and tested to compile correctly under Turbo Pascal (R) 
versions 5.0 through 6.0. 

Constants

Vertical_Iterations -   A variable word value that defines the number of vertical 
interactions or loops, lines, sections used to make the frame.

Horizontal_Iterations -  A variable word value that defines the number of horizontal 
interactions or loops, lines, sections used to make the frame.

Procedures

Set_Frame_Color -  A procedure that sets the drawing color used by the frames 
procedures to draw their frames.

Draw_Frame1 -  A procedure that draws a single curly frame with outward extending 
ends.

Draw_Frame2 -  A procedure that draws a single curly frame with inward extending 
ends.

Draw_Frame3 -  A procedure that draws a double curly frame with outward 
extending ends.  

Draw_Frame4 -  A procedure that draws a double curly frame with inward extending 
ends.

Draw_Frame5 -  A procedure that draws a frame of inward looping curls.

Draw_Frame6 -  A procedure that draws a frame of outward looping curls.

Draw_Frame7 -  A procedure that draws a frame with lines rounding off the corners.

Draw_Frame8 -  A procedure that draws a simple line frame with line points 
emerging from the corners.

Draw_Frame9 -  A procedure that draws a simple line frame with a line point 
emerging from the left and right sides.

Draw_Frame10 -  A procedure that draws a simple frame with a line point emerging 
from the top and bottom.

Draw_Frame11 -  A procedure that draws a simple frame with two line points coming 
out of the top and bottom.

Draw_Frame12 -  A procedure that draws a double frame with boxed corners.

Draw_Frame13 -  A procedure that draws a double frame with criss-crossed lines 
between the frames.

Draw_Frame14 -  A procedure that draws a double frame with criss-crossed lines 
between the inner and outer frames.

Draw_Frame15 -  A procedure that draws a frame consisting of overlapping arcs.

Draw_Frame16 -  A procedure that draws a frame on inward arcs.

Draw_Frame17 -  A procedure that draws a rounded box frame.

Draw_Frame18 -  A procedure that draws an inwardly rounded box frame.

Draw_Frame19 -  A procedure that draws a downward scroll frame.

Draw_Frame20 -  A procedure that draws a upward scroll frame.

Chapter 39

The Look unit

Version 1.0b - Beta

        Welcome to the Look unit.  This unit is one of my more limited units as it simply is 
designed to take a quick look at the hardware on which it is running.  Which brings me to it's 
purpose.  Have you ever needed your program to know exactly what type of machine is 
running on?
        If you answered yes to that question, then this is it. That's where look comes in.  It's 
specially designed to detect that sort of information in a most standard way using the safest 
methods possible.  Well, almost.  I've tested it on every machine I've come across and it 
works great.
        Anyway, the look unit is designed to test processors and video cards as of right now.  In 
the future, however, I hope to expand it for detecting additional hardware.

How does it work?

        The Look unit uses different methods depending on the tests it's running.  The processor 
test makes use of a special feature of the CPU's flag register to determine which type of 
processor it's running on.  The core code is available from Intel and naturally, it's in 
assembler.  I've modified it to work with Turbo Pascal.
        The video adaptor on the other hand uses a series of mode change calls that I devised 
myself to determine the allowable video modes.  You see, the PC's basic input/output system 
(BIOS) takes care of handling video mode switches for you if you let it.  My code, by 
requesting a mode switch and then verifying it it worked or not, goes through a series of 
requests to determine which modes are allowed and which aren't.  Using this technique it can 
determine video adaptors all the way up to SVGA.  (Note that some adaptors that bill 
themselves as merely VGA also allow for unofficial modes like the SVGA cards)
        This unit relies on Turbo Pascal's (R) DOS unit for performing the interrupts necessary to 
call the system BIOS.

Are there any limitations?

        When running the code under a more advanced operating system like OS/2, the operating 
system has more control over the allowable video modes for a particular session.  Under such 
circumstances, the code will only be able to detect what the operating system wishes it to 
detect.
        The only other limitation that I can think of is that the unit has not been verified with the 
80486 class processor, nor the Pentium class processors, yet.  Hay, I still can't afford one of 
them at this time.

How to use

        Since there are only two functions in the look unit at this time it's very easy to detail the 
use of the unit.  In fact it's sort of silly here since the LookDemo file has the same basic stuff, 
but here goes.
        The first thing you need to do is inform the processor that you intend to use the Look 
unit.  This is accomplished by including the name in your program's uses clause.  For 
Example...

        Uses
          Look;

        Now wasn't that simple?  Next you merely use the two functions in your program where 
you need to determine the piece of hardware.  For example...

        Var
          Processor_Type: Word;
          ...
        Begin
          ...
          Processor_Type = Test_Processor;
          ...

        That was easy, wasn't it?  Processor_Type will now hold a word value that reflects the 
processor type it's used on.  The possible values that it can hold are:

        86 for the 8088, the 8086 and the 80186 and compatible.
        286 for the 80286 and compatible.
        386 for the 80386, the 80386dx and the 80386sx and compatible.
        486 for the 80486, the 80486sx, the 80486dx/2, the 80486dx/4 and compatible.
        586 for the Pentium (R) and the compatible.
        ? for the Pentium Pro and compatible.  (I haven't got around to this one yet.)

        Testing the video system is just as simple.  The results are returned in a character 
variable and uses a simple code to do it.  Heres a sample of how easy it is.

        Var
          Character: Char;
          ...
        Begin
          ...
          Character = Test_Video_System;
          ...

        That was it!  Now the Character variable holds a value that reflects the video system on 
which it's running.  The possible codes are as follows.

        'H' defines a Hercules (R) video adaptor.
        'M' defines a monochrome display adaptor.
        'C' defines a color graphics adaptor. (4 colors in graphic mode)
        'E' defines a enhanced graphics adaptor.  (16 colors in graphic mode)
        'G' defines a multi-color graphics array.
        'V' defines a video graphics array.
        'X' defines an extended graphics array.
        'S' defines a super video graphics array.

        That's about it.  If you'd like to see the unit in action take a look at the LookDemo 
program and try it out.  

Which compilers are supported?  

        This unit has been designed and tested to compile under Turbo Pascal (R) versions 4.0 
through 6.0

Functions

Test_Processor -  This function performs a test on the system's micro-processor to 
determine it's classification.  The result is returned as a word number.

Test_Video_System -  This function performs a series of tests on the system's video 
card to determine it's classification.  The result is returned as a character.

Chapter 40

The TextCorrect unit

Version 1.34 - Beta

        Okay, I've been working really hard on this one, but haven't seemed to make any really 
worthwhile improvements. It seems that B_Tree really doesn't like keys shorter than 6 bytes 
in length, at least not with thousands of records to manage.  Therefore, all the enhancements 
to this update are minor.
        The TextCorrect unit is an enhancement to the TextEdit unit which adds a spelling 
checker to the system.  It's very quick and easy to work with and best of all, interlinks 
directly and seamlessly into the unit.
        The TextCorrect unit includes a good helping of special features that I'm sure you'll 
appreciate.  Here are just a handful of it's special features, for a complete list, see the unit's 
heading.
        TextCorrect uses the Soundex coding system to provide quick word key looping using 
phonetic word matches. It recognizes and flags words that should be capitalized and 
automatically capitalizes them if instructed to.  Easily allows new words to be added to either 
the main dictionary or personal dictionaries.
        TextCorrect also features an AutoCorrect facility which holds permanent corrections.  
This feature allows you to carry a word correction across all your documents, not just your 
current one. Oh, and one of my favorites, the status display.  Not only can you see where you 
are in the document, you can actually see how fast the system is working.
        And let's not forget the word counting facilities.  It keeps track of how many words in 
your documents, how many were flagged, now many were altered and more.
        The following activation keystrokes are added automatically to the TextEdit unit 
command list.

[Ctrl]QL - to start spell checking at current cursor location.
[Ctrl]KL - to start spell checking at beginning of block.
[Ctrl]QW - to spell check the current text line.

How does it work?

        The TextCorrect unit stores the dictionary in multiple BTree file structures divided by 
word size and keyed by a special Soundex code generated for each word.  This enables the 
TextCorrect to call up multiple sound alike records for each word it doesn't recognized.  It 
also makes it fast in operation.  As a matter of fact, this system has been designed to allow 
word dictionaries of enormous size to be created.  So, there's no reason why a single 
dictionary, disk space permitting, can't contains words from several different languages in it.
        When the system checks a word, it first generates a Soundex key code to use to look up 
the word.  Then after determining the words length, the system looks up the word in the 
appropriate dictionary.  If the word is found, then the spelling must be correct, otherwise, it 
flags the word as suspect and goes on to look for it in one of the other places. If the word still 
isn't found, all the possible alternatives are sought and placed in a word list which is in turn 
presented to the user for selection or rejection.
        The TextCorrect unit relies on Turbo Pascal's (R) CRT unit.  It also relies on BTree, 
Core, KeyBoard, TextLine, TextEdit, TextLink, String_Utilities and Generate_FileName.

Are there any limitations?

        The most pressing drawback of the current implementation of the TextCorrect unit, I 
think, is it's inability to store the dictionaries in a compressed format.  Compression is a 
feature common among the more professional spell correction systems because it saves disk 
storage space.  Perhaps I'll include this feature in a future versions, or perhaps not.  Who 
knows?  Anyway, don't alter the code in this unit without taking note that specifications for 
parts of it may change without notice.
        Also note that user separated words are not singularly checked during the word search.

How to use

        Unless you're planning on altering the interface, or using the two additional routines in 
your program, the TextCorrect is probably the easiest unit in the library to use provided your 
code is already set up to accommodate the TextEdit unit which is perhaps one of the most 
difficult.  But, I guess it is for this very reason, that TextCorrect is easy.  Anyway, in order to 
include the TextCorrect feature to the TextEdit code, simply put the TextCorrect reference in 
your program's uses clause.  Example.

Uses
  ...
  TextCorrect
  ...;

        That's about all there is to use it.  Oh, yeah! If you wish to substitute your own routines 
in the unit, just replace the variable procedure and functions with those of your own device.  
This makes it very easy to create a consistent user interface of your own design.

Which compilers are supported?

        The TextEdit unit has been designed to compile correctly with Turbo Pascal (R) versions 
5.0 through 6.0.

Constants

AutoCapitalize -  This switch, when set to true, allows the system to automatically 
capitalize any word it thinks should be.  Otherwise it's presented to the user to 
decide.

AllowBackgroundChecking -  This switch, when set to true, allows the system to 
continue the spell checking while it waits for the user to make a decision.  
Otherwise all background activity is deactivated.

Use_Unique_FileName - This switch, when set to true, allows the system to 
generate a unique name for it's temporary file, otherwise it uses the old method 
of using a default file name.

Types

Info_Type -  (Information type)  This defines the information about a word that can 
be stored in the word record.  Currently it only tells if the word should always be 
capitalized or not.

Variables

Prepare_Screen -  This variable procedure is called before a word will be flagged on 
the screen.  You may include a replacement for it if you wish.  (See the unit's 
header for more information)

Display_Word -  This variable procedure is called to display the suspected word on 
the screen.  You may include a replacement for it if you wish.  (See the unit's 
header for more information)

Get_Suggestion -  This variable procedure is called to accept a suggested word 
replacement from the user.  You may include a replacement for it if you wish.  
(See the unit's header for more information)

Display_Suggestion -  This variable procedure is called to display a word suggestion 
on the screen for the user's use.  You may include a replacement for it if you 
wish.  (See the unit's header for more information)

Offer_Options -  This variable procedure is called to show all the possible choices 
when there is a suggestion and receive a choice decision from the user in the 
form of a character command.  You may include a replacement for it if you wish.  
(See the unit's header for more information)

Offer_Options2 -  This variable procedure is called to show all of the possible 
choices when there isn't any suggestion and receive a choice decision from the 
user in the form of a character command.  You may include a replacement for it if 
you wish.  (See the unit's header for more information)

Out_Of_Suggestions -  This variable procedure is called when there are no more 
suggestions in the list.  It merely displays a message before it returns.  You may 
include a replacement for it if you wish.  (See the unit's header for more 
information)

Prompt_To_Capitalize -  This variable procedure is called when a word is being 
flagged as a candidate for capitalization.  It displays the capitalize screen and will 
perform the change unless the user presses escape.  You may include a 
replacement for it if you wish.  (See the unit's header for more information)

Prompt_For_Capitalize -  This variable function get's the user's choice for the 
Prompt_To_Capitalize variable procedure.  The choice is returned in the form of 
a character command.  You may include a replacement for it if you wish.  (See 
the unit's header for more information)

Ask_Global_Replacement -  This variable function is called after the user decides to 
perform an alteration instead of accepting a suggestion.  It returns a character 
command if the user wishes the alteration to be performed in the entire 
document.  You may include a replacement for it if you wish.  (See the unit's 
header for more information)

Clear_Options -  This variable procedure is called after the entire decision process is 
finished, to clean up the screen.  You may include a replacement for it if you 
wish.  (See the unit's header for more information)

Display_Status -  This variable procedure is called to display all of the text checking 
results at the end of the entire operation.  You may include a replacement for it if 
you wish.  (See the unit's header for more information)

Write_Search -  This variable procedure is called to display the fact that the program 
is searching the system for a particular dictionary file.  You may include a 
replacement for it if you wish.  (See the unit's header for more information)

Procedures

Read_Dictionary -  This procedure reads in a word dictionary from the text file of the 
given name into the main dictionary without prompting for permission.  It's 
primarily intended to be used for initially building a dictionary.

Write_Dictionary -  This procedure writes all of the words in the main dictionary into 
a text file of the given name.  It's primarily intended to be used to dump the 
dictionary to a text file.

Error Codes

1000 -  Generated by unit if an error occurs when opening a read dictionary text file.

1001 -  Generated by unit if an error occurs when reading from a dictionary file.

1002 -  Generated by unit if an error occurs when opening a write dictionary text file.

1003 -  Generated by unit if an error occurs when writing to a dictionary file.

Chapter 41

The WindExtra unit

Version 1.01 - Beta

        The WindExtra unit is a specially designed unit which works on top of  the KeyBoard, 
Pointer and one of the windowing units, increasing their interconnectivity.   It adds various 
pointer selected buttons along the edges of the current window frame.  Designed to work 
with either the Window unit or the Multiple unit, this unit doesn't need either to operate.  
Rather, it works as a stand-alone enhancement.
        Okay, I know what you're thinking.  What exactly does the WindExtra unit do? 
        Well, what the WindExtra unit actually does is it puts a various assortment of function 
buttons along the frame of the current text window defined  by the CRT unit.  Then by 
interlocking into the KeyBoard unit, whenever the user is inputting data through a routine 
that relies on the KeyBoard unit and the pointer system is operational, button selection 
through the pointer will translate into certain cursor movement keystrokes.
        Buttons are added that when clicked or double clicked will either close the window, 
escape from the current routine, move the cursor in any of the directions, move through 
pages, and finally move the window anywhere on the screen.

How does it work?

        The unit inserts a special routine which intercepts pointer codes before they are 
exchanged from the Pointer unit to the Keyboard unit.  Then they are remapped, depending 
on the location of the current pointer into other new keystroke commands.
        This unit depends on the CRT unit and relies on the Core, Pointer and KeyBoard units 
for other aspects of it's support.

Are there any limitations?

        There are several limitations to the WindExtra unit.  First and foremost, it doesn't work 
very well in graphical modes.  Second, since it was designed to work with both the Windows 
and Multiple units, it doesn't look for either one and therefore only assumes the units are 
being used at all.  Therefore it doesn't check to see if the current window has a frame or not 
and must assume it does.
        In order that the unit be completely self contained, no other links are established except 
with the KeyBoard and the Pointer units.  This reduces the possible features, but expands the 
flexibility of the unit for the programmer's use.

How to use

        First, the WindExtra routine is very easy to use.  In fact, it contains only one procedure 
and that's it.  Barely anything is left that can possibly go wrong.  Here's an example that 
illustrates how you may use the WindExtra unit in your code.   This example draws from the 
window unit, so please bare with me if you haven't a clue as to what's happening.
        First, our example must declare to the compiler that it wishes to use the WindExtra unit.  
This is very easy to do through the USES clause.  In addition, this example will make use of 
the Window unit.

Uses
  Window,
  WindExtra;

        See!  That's all there is to it.  Now let's see what happens somewhere in the code when 
we wish to use the WindExtra procedure.  Let's assume that something is in the window that 
we wish to allow our user the opportunity to browse.

Begin
  ...
  If Open_Window( ... )
    then
      If VW_Create( ... )
        then
          Begin
            ...
            { Here assume the code puts something in the
              window }
            ...
            Add_Interface;
            VW_Browse;
            ...
            Close_Window( ... );
          End;
  ...
End.

        Note the placement of the Add_Interface before the browse routine, which incidentally 
uses the KeyBoard unit.  That's the extent of using the WindExtra unit.  There's nothing more 
that you need worry about.  The Window will retain the extra features until it's closed.  Also 
note that if the window is altered in size or shape, it's a good idea to call the Add_Interface 
routine so that it can redraw the buttons on the window frame.

Which compilers are supported?

        This unit was designed and verified to compile properly under Turbo Pascal (R) version 
5.0 through 6.0 and under Speed Pascal/2 version 1.5.

Constants

Wait_Time -  This constant defined the delay period that the code pauses after the 
command is generated before it's passed along to the KeyBoard unit.  This 
provides much better control of the pointer.

Procedures

Add_Interface -  This procedure must be called after the window is drawn on the 
screen and before any routine that relies on the KeyBoard is used, such as the 
routines from the Editor, Menu or TextEdit units.

Glossary

 8080.  A third generation microprocessor designed by the Intel (R) corporation which is used to operate 
some of the earlier microcomputer systems.  It has a 8 bit data bus and word size.  Memory size is 64 
kilobytes.
 8086.  A forth generation microprocessor designed by the Intel (R) corporation which is used to operate 
some of the IBM (R) compatible computers.  Has a 16 bit data bus, 16 bit words and has a memory 
size of 1 megabyte.
 8087.  A microcoprocessor designed to accompany the 8086 and perform floating point operations for it 
really quickly.
 8088.  A forth generation microprocessor designed by the Intel (R) corporation which operates almost 
exactly like the 8086.  It was the chip of choice for the original IBM-PC (R) and has an 8 bit data bus 
with 16 bit words.
 80186.  A forth(?) generation microprocessor designed by the Intel (R) corporation which is used by a 
very few microcomputer systems.  It's close to the 8086, but has a few added enhancements.
 80286.  A fifth generation microprocessor designed by the Intel (R) corporation which is used in IBM - 
AT (R) compatible microcomputer systems.  It uses a superset of the same machine code of the 
8086, but also includes features that allow protected multitasking.  Has a 16 bit data bus.  Not very 
popular for a few shortcomings.
 80287.  A microcoprocessor designed to accompany the 80286 and perform floating point operations 
for it really quickly.
 80386.  A sixth generate microprocessor designed by the Intel (R) corporation which is used in many of 
the IBM-AT (R) compatible microcomputer systems.  It's a different breed of microprocessor 
altogether but has the ability to operate with the same machine code as the 8086 and the 80286 in 
addition to it's own code.  It has either a 16 or 32 bit data bus and features 16 or 32 bit words 
depending on the mode it's in.  It has much better multitasking abilities than the 80286.
 80387.  A microcoprocessor designed to accompany the 80386 and perform the floating point 
operations for it really quickly.
 80486.  Considered the seventh generation microprocessor of the sequence, it's essentially a really 
fast 80386 microprocessor with a built in memory buffer and may or may not include an internal 
coprocessor.  This one features a 32 bit data bus and features 16 or 32 bit words like the 80386.
 Ada.  A neat high level programming language packing plenty of power.  Named after the countess of 
Lovelace, considered to be one of the first programmers.  (Well, it's an honorary title)
 Allocate.  To set aside.  To reserve for a specific purpose.
 Animation. An effect achieved by the rapid altering of a picture to give the appearance of movement.  
Something graphical computers are quite good at.
 APL.  A very powerful and concise programming language.  Easy to work with, but a nightmare to 
update.  Everything is viewed of as tables or arrays.
 Application.  A new  word for a program.  Sounds so much more sophisticated, doesn't it?
 Approximation.  A computer's best guess, which really isn't all that bad.
 ANSI.  Basically anything this refers to has a general accepted or standard way of doing it.  (It's by a 
standard committee that sits around thinking about how everyone should do it)
 ASCII.  A standard code used by many computer makers to encode characters and file control 
symbols. 
 Assembler.  A low level programming language, once removed from machine code.  Assembler is 
considered difficult to work with and isn't portable because it varies drastically from one machine to 
another.  Assembler is the most powerful of the programming languages.
 Attribute.  A piece of information that specifies how something is to happen or used to describe some
thing.
 Background.  On the screen, something that doesn't have the prominent status.  Something that is 
happening behind the scene such as by the stagehands.  (Yes, there really are stage hands working 
somewhere in your computer)
 Bar menu.  Something you ask for down at the corner pub.  Seriously, in computer terms, this is a 
menu presented across a single text line.  Some prefer the word ribbon.
 BASIC.  A popular and easy to use programming language.  BASIC isn't as structured or as versatile 
as Pascal, but easy to work with none-the-less.
 Binary.  Pertaining to two, such as either it's there or it isn't.  On or off, Male or female, get it?
 BIOS.  Acronym for the Basic Input Output System.  A series of internal code routines that provide a ba
sis to operate the fundamental interfacing between the computer and the hardware that makes up the 
input output devices.  Of primary importance.  Without this stuff, your computer is totally worthless.
 Bit.  Acronym for binary digit.  Smallest possible piece of information. (see binary)
 Bold.  A laundry detergent.  A modification to a font which makes it more prominent.
 Boolean.  A system of mathematics involving two states of the condition of a situation, either true or 
false.  Used by the compiler to assess a situation and determine the course of action.  (Did that make 
any sense?)
 B-Tree.  A special data storage structure that somewhat resembles a tree in that each record has multi
ple branches or links to other records.  Works nicely for rapid record finding.
 Bug.  An error in a program, usually a logical error or an oversight. Also a pesky insect.
 Button.  A key on the keyboard, the switch on the pointer unit,  the computer's on and off switch, and 
sometimes a graphical representation on the screen that you position the pointer on and click the 
pointer's button.
 C. A much too popular, cryptic and bloody awful programming language.  Probably revered by 
programmers for the same reason, I hate it so much.  Often called a portable assembler language.  
 Caps Lock.  A switch on the keyboard that alters the functions of the letter character keys.  (Note that 
the numbers are not affected)  Toggles the uppercase and lowercase characters.
 Char.  A character.  A type defined to hold a single character of information.
 Click.  The sound made when you press any button connected to your computer,  The sound made by 
your computer when it doesn't like what you've just tried to do,  and finally the act of pressing and re
leasing the button on your mouse or trackball.
 Clipboard.  An area that allows information to be put into it so that it can be moved to some other 
place.
 Clock.  An internal time keeping device by which the computer paces it's activities.  An external time 
keeping device by which you pace your activities.
 Close button.  An area on the window frame that when clicked with the pointer, closes the window.
 COBOL.  A high level programming language that's very popular with business applications.  Most of 
the programs in existence are written in this language.  COBOL is very easy to read and write.
 Compatible.  Identical or nearly so.  Operating with the same parameters or something that mimics 
another.  A compatible computer can use the same software, a compatible printer can print as if it 
were the other.
 Compile.  The process of translating from one code (Source) into another. (object or machine code)
 Compiler.  A computer program (application) capable of generating machine code from a text file.
 Compliment.  To provide an enhancement or encouragement.  A comment directed to another to pro
duce a desired result such as approval.
 Compression.  A system that squeezes the information into a much smaller amount of space.
 Constant.  In Pascal, a piece of information that doesn't change during the course of a program's run. 
A variable constant (a contradiction in terms?) is a variable that starts off as a constant but is allowed 
to change with necessity.
 Coprocessor.  An assistant to the processor who get's handed all the dirty work that the processor it
self doesn't like to do.  The processor is terribly lazy at doing floating point math.
 CPU.  Central processing unit, or the microprocessor.  The part of your computer system that seems to 
get the most exercise and attention.
 CRT.  A seeming archaic way for a programmer to refer to the monitor screen.  Stands for cathode ray 
tube which isn't even always what makes up the computer's monitor. I basically use it to confuse the 
user and to make it easy to match up the unit conventions. (see screen or monitor)
 Cursor.  The little line on the screen that almost always blinks on and off at you.  It displays where your 
next character of text is going to appear on the screen and sometimes is way to small to notice.  
Please don't confuse the cursor with the pointer. The pointer doesn't blink.
 Data.  The weird name that programmers wish to give to any little piece of information they find.  Also 
(with a slightly different pronunciation) the name of a very popular fictional android.
 Database.  Basically an electronic filing system that offers incredibly quick searching.
 Debugging.  The act of removing logical errors from instruction code.  Named after the physical act of 
removing insects from the insides of early computer equipment.
 Denominator.  The lower part of a fraction.  See Numerator and your junior high school math teacher.
 Descendent.  Routine that depends on another for some of it's work.
 Determinate.  Oh, boy!  Hoped you didn't need this one.  Better dig out your old collage mathematics 
book to check this one out.  In short, though it's a very useful function in high level mathematics.
 Directory.  In DOS terms, a collection of files and/or subdirectories.
 Disk.  A form of permanent data storage around which whole operating systems have been written.  
Your computer's universe revolves around this revolving disk.
 Disk cache.  A place set up in memory by a cool program or driver that acts as an exchange table be
tween the disk and the program.  Makes your system really fly.
 DOS.  Acronym for disk operating system.  Also, a Turbo Pascal (R) unit which provides and interface 
between a program and the operating system. A list of desirable activities.
 Double click.  The act of clicking the pointer device button twice in rapid succession.  A very big pain 
which everyone hates but seems to love at the same time.
 DoubleStrike.  A method of emphasis which increases a font's darkness by striking each character 
twice.
 Drag.  The act of holding down the pointer device button while the pointer is moved around the screen.  
This is often used to select text and to move files on certain operating systems.
 DR-DOS.  A disk based operating system developed by the Digital Research corporation.
 Elite.  The most standard of fonts supported by most printers that prints at twelve characters to the inch.
 Emphasize.  To make more prominent by altering in some manner.  See highlight.
 Field.  Specifically referred to as a portion of a record.  A small piece of information that is attached to a 
larger unit.  A clearing of land covered with pretty flowers, grass and weed.
 File.  A structure of the disk operating system which holds data.  A file can hold data or a program or 
even a combination of both or neither if you'd want it to.
 Floppy disk.  A more friendly and more traveled version of the disk around which the computer's uni
verse revolves.  It's also floppy which means it moves around a little bit slower.
 Font.  A particular style of type used by the computer or printer or other output devices. Most printers 
have a few different ones built in.
 Footer.  The area at the bottom.  A note at the bottom of the page.
 Foreground.  On the screen, the text.  In the system, the computer program that has the primary at
tention of the user or has center stage. (See background)
 Format.  The way or style in which something is laid out or arranged.
 FORTRAN.  A popular high level language among engineers and scientist. Of moderate power, this 
language has a very rigid line format.  FORTRAN focus is mainly on numbers.
 Frame.  The act of setting someone up. A support system around which something is built.  A border 
for a window.
 Function.  A code routine in Pascal which accepts a few parameters then takes control of the 
computer for a moment and returns a little something when it's finished.  
 Function key.  One of the several available keys that appear on the IBM compatible computer key
boards.  Each program likes to make it's own use of such keys and why shouldn't they?  That's what 
they're there for.  Take note that certain keys are often reserved for specific functions.  (See help key) 
 Graphic.  Pertaining to the ability to draw things on the screen without limit to the shape of the object 
drawn. 
 Hard disk.  A more adult and more rigid version of the disk.   It's also much larger and much faster 
and generally a requirement for any of the more advanced operating systems.
 Header.  The area at the top.  Of or preceding all others.
 Heap.  Sort of like a sea of memory address from which memory blocks may be obtained.  I like to think 
of it as a vast array of computer consciousness filled with thousands of disorganized little computer 
thoughts. Allocating from it is like lassoing icebergs from a dock.  (I'm really weird, aren't I?)
 Help key.  The first function key, is always reserved to be the help key unless it tells you specifically 
that it's not.  Everyone expects the F1 key to call up the help screen and all programs do so with the 
one exception of the WordPerfect (R) program which probably explains it's popularity.  (Go figure)
 Highlight.  A special way of displaying something that makes it stand out from the rest.
 Horizontal.  Pertaining to the horizon.  Normally stretched out left to right or along the X axis.
 Icon.  A pretty picture used by many of the more popular operating systems like OS/2 and DOS through 
Microsoft Windows to represent objects, operations or files.
 Interlink.  A link that's performed internally so that there are no visible seams.
 Interrupt.  An annoying disturbance which disrupts normal tasks.  In computer terms a routine that mo
mentarily takes over the computer system, either invited or not, to perform a simple task.
 Italic.  A font style that takes normal characters and slants them slightly to the right.
 Joystick.  A computer input device consisting of a vertical stick mounted on a base.  Which allows in
put to be generated by tilting the stick in relation to all sides of that base.  Usually includes input but
tons as well.
 Justify.  The act of defending ones choices by generating a group of excuses.  In computer terms, the 
movement of a block of text to the right or left relative to the center of the page.
 Keyboard.  The typewriter style arrangement of buttons (Keys) that sits directly in front of the monitor 
so that you can input characters into your computer. 
 Kilobyte.  Represents a thousand bytes or more specifically 1024 bytes.
 LCD.  An alternative form of screen displaying technology and a good reason why the term CRT should 
be removed from computer programming usage.
 Library.  A collection of routines or modules.
 Lightpen.  A cool input device, almost impossible to find anymore, that allows the selection of an 
object on the screen by pointing the light pen directly at it.
 Limitation.  Shortcomings. Situations that can't be handled. Something everything and everybody has 
weather they admitted it or not.
 Lisp.  A very high level programming language used for artificial intelligence.  Lisp has many logical list 
processing features but lacks adequate commenting.  Lisp is good for list processing tasks.
 Machine code.  Code that the computer can directly understand and that constitutes an application 
or program.  (Most programs are distributed as Machine code)
 Margin.  The border.  A degree of advantage.  A area of safety between the working area and the ex
treme degree.
 Math coprocessor.  A specialize processor that assists the CPU when it's overloaded with lot's of 
mathematical work.  The CPU can usually do the work itself, but why should it if this much quicker lit
tle helper is available to assist it. 
 Matrices.  The plural of matrix.  A collection of matrix.
 Matrix.  A multidimensional collection of objects.  A common example is your ordinary egg-carton.
 Maximum.  A Latin based word meaning the largest allowable. (see minimum)
 MDOS.  A subsystem of OS/2 that allows PC-DOS compatible programs to operate in the multitasking 
environment.
 Megabyte.  Represents a million bytes or more specifically 1024 kilobytes.
 Memory.  The actual space that the computer puts the program and data that it's working on.  It works 
much in the same way you remember a math equation from a book before the big math exam and 
then immediately forget it afterwards when you turn to something else.
 Menu.  A list of available options arranged onto the screen in such a way that you usually get to choose 
one and only one.
 Microcomputer.  A machine that combines a micro-processor, a memory unit and various in
put/output devices to manage data.
 Microprocessor.  A general purpose machine that performs operations on data following a 
sequence of codes.
 Minimum.  A Latin based word meaning the smallest allowable.  (See maximum)
 Module.  Separable section of code that performs a task which may be of use to a variety of different 
programs.
 Modula2. A successor to Pascal, this programming language features most of the better elements of 
it's forbearer with some new ones added.  Turbo Pascal has evolved slightly past the advantages of 
Modula2.
 Monitor.  The specific video screen upon which most of the immediate output is displayed.  (See 
screen or CRT)  Not to be confused with the general screen.
 Mouse.  A specific style of pointing device, much like an upside down track ball.  Also a small shy ro
dent that watches you from the kitchen as it searches for snacks.
 Mouse button.  A button on the mouse. (Wasn't that Easy?)
 Mouse pad.  A duplex upon which a mouse resides.
 MS-DOS.  A disk based operating system developed by the Microsoft corporation.
 Multitasking.  The process of performing two or more tasks at the same time by allowing a small inci
dent of time to be devoted to working on each in turn, one then the other and so on.
 Node.  Generally a collection of data records incorporated into a specific data cluster.
 Numerator.  The higher or top portion of a fraction.  See Denominator and your junior high school 
math teacher.
 Object code.  Semi-Machine code generated by a compiler or assembler that's one step removed 
from normal machine code.
 Overlay.  A feature that allows two modules of code to occupy the same location in the memory, but 
not at the same time.  Special code takes care of swapping the code segments.
 Object orientation.  A code philosophy that ties the code and data into one structure.  Under the 
right circumstances, it can be very liberating to the programmer.  When used wrongly, however, it 
leads to an excessive amount of code bloating.
 OS/2.  A disk based multitasking operating developed by the Microsoft corporation and the IBM corpora
tion.  Discontinued by the former and vastly improved by the later.
 Pascal.  Blaise; A great French mathematician, scientist,  inventor and philosopher.  Also a great 
structured programming language created by Prof. Niklaus Wirth in the early seventies.  See Turbo 
Pascal.
 Password.  A mutually accepted word or phrase used to provide a means of identifying oneself and 
gaining access to something but preventing the same to others by secrecy. Usually forgotten by the 
person wishing to gain access at the worse possible moment.
 Parameters.  Special pieces of information that are handed to a routine to specify how or what's done 
to what.  Variable parameters may be altered by the routine, while the others aren't.
 PC-DOS.  A disk based operating system developed by the Microsoft corporation and licensed by the 
IBM corporation.
 Pentium (R).  Considered the seventh generation microprocessor from the Intel (R) corporation, it's 
also used in microcomputer systems and is essentially a much faster 80486 microprocessor with a 
few new enhancements added.  It features a 64 bit data bus and features 16 or 32 bit words too.
 Pica.  The most standard of fonts supported by most printers that prints at the rate of 10 characters to 
the inch.
 Pixel.  A single picture element.  Also retains to a variety of fairy.
 PL/I.  A neat high level programming language.  Has many of the better features of Pascal and some of 
the other programming languages.
 Pointer.  The blot of video or little picture that moves around on the screen when you move your point
ing device around on the table.  They are connected together with a little bit of electronic thread. (Just 
kidding!)
 Poll.  A method of obtaining information by taking an occasional look at what's happening.  Similar to 
the way most people check up on a oven to verify the status of their meal as opposed to setting the 
timer and removing the food when the timer goes off. An excuse an unexpected visitor gives you for 
interrupting dinner.
 Pop-up.  A method of appearing instantaneously.
 PPTool-Kit.  An acronym for the Pascal Programming Tool Kit.  I had to name it something!
 Printer.  An output device for the permanent recording of a file.
 Procedure.  A routine which in Pascal accepts parameters and takes over control of the computer for 
a short time.
 Process.  The act of transforming something into another form.
 Processor.  Another name for the CPU.  The part of the computer that gets all the attention, all the 
fame and all the glory.
 Project.  A specific computer program or specific purpose unit.
 Program.  A computer application.  A file that holds machine code which give the computer directions 
to perform a special task.
 Queue.  A data structure that operates in exactly the same way that people wait their turn in a bank.  
The data objects are placed in at one end of the data structure and removed from the other end.
 Random.  Out of sequence.  Of having no order or rhyme.  A number generated by some mysterious 
unpredictable method.
 RAM.  A male sheep.  Also an acronym pertaining to a type of computer memory; Random access 
memory.  Believe it or not, there was such as thing as sequentially accessed memory at one time.
 Real.  The opposite of phony.  In Pascal terms a number that is of the real status as opposed to 
integers and imaginary numbers.  Real numbers are stored in a very limited floating point manner.  
Ironically, with computers real numbers are often approximations!  Go figure. 
 Record.  A packaged collection of distinct but related pieces of information.  A collection of attributes 
pertaining to a specific instance.  (Insert other dull stuff here)
 Region.  Area. Divided off section. Particular to a local setting.
 Resolution.  Pertains to the capability of a device to clearly display images on it's screen.  The higher 
the resolution, the clearer the images can be displayed.  Also a vow.
 REXX.  A really cool interpreted programming language. All variables are handled as strings. Also the 
name someone would probably give a really cool dog.
 ROM.  An acronym pertaining to another type of computer memory; Read only memory.  It usual sup
ports being randomly accessed, but it's not alterable. CD's can be read, but not altered hence 
CD-ROM.
 Routine.  A section of code or instructions that performs a single specific task.
 Scalar.  Pertaining to a scale of some sort.  Having magnitude but no direction.  A pure number 
representing only one magnitude.
 Screen.  The foremost or primary output system of the microcomputer system.  It's the television like 
display that everyone looks at for hours on end. (See monitor or CRT)
 Scroll.  A document of ancient origin.  Also the act of moving the view area to a different part of a large 
document.
 Scroll bar.  A object on the right side or bottom of a window that displays buttons, and using an adjust
able little elevator, the relative position of the window view in the entire virtual window.
 Shareware.  A neat concept that allows the free distribution of software, but requires payment for con
tinued use beyond a trial basis.  See TrialWare.
 SIMM.  A memory module designed to simplify the task of increasing system memory.  Otherwise you'd 
have to push the tiny memory chips into the memory bank one by one.  A painful process in more 
ways than one.
 SNOBOL.  A high level programming language in which everything is viewed as string structures.
 Software.  A generic term given to any type of program that the computer works with.  From the early 
days of computers used to differentiate the hard (physical) aspects of a computer system from the 
soft (mental) aspects.  Both are equally important, however.
 Soundex.  A coding system developed by the telephone company that replaces certain characters 
with numerical values to render similar sounding names the same numerical values.
 Speed Pascal/2 (R).  A nice Pascal compiler by SpeedSoft (Vision Software) for the 80386+ 
microcomputer platform. Speed Pascal/2 contains all the best features of Turbo Pascal but is built for 
a 32 bit platform.   Speed Pascal/2 (still in the beta stages) is a very promising programming 
environment that takes over where Borland left off.
 Stack.  A term used for a data structure that operate much like a toybox.  You must remove the top ob
jects to get at the goodies underneath.
 String.  A length of material.  A collection or group of characters.
 Submenu.  A menu that's normally hidden beneath the menu above it.  You have to get through a pre
vious menu to usually get to this one.
 Subroutine.  See procedure or function.
 Subscript.  A font alteration that moves the text slightly lower on the line.
 Superscript.  A font alteration that moves the text slightly higher on the line.
 Table.  An elevated platform upon which your computer sits.  Also another form of matrix.   
 Tangible.  Physical object.  Something you can see, touch, feel... (You get the picture)
 Text.  Characters or figures combinations that aren't icons (that's a help ) that are displayed on your 
monitor screen or on the printed paper.
 Text mode.  A special mode of your computer monitor which only displays text.  Text characters are 
controlled as a predefined block of characters which you can't normally alter.
 Toggle switch.  A switch which moves in either one of two directions and stays that way.
 Trackball.  An alternative input device that usually leaves your wrist in a little better shape.  It also 
makes double clicking much less painful.  (See mouse)
 Transpose.  To reverse or change the order of. 
 TrialWare.  A form of software marketing in which the user is given the opportunity to try a piece of 
software on a trial basis before deciding if he or she wishes to pay for it and continue using it.  It 
works on an honor system. 
 Turbo Pascal (R).  A very robust Pascal compiler by Borland International for the IBM PC 
microcomputer platform.  Turbo Pascal combines all the best features of Pascal with the modularity of 
Modula2.  For OS/2, Speed Pascal (Still a beta product) seems to look very promising.
 Type.  A Pascal directive that allows the user to explain to the compiler exactly how a data structure is 
to exist.  A method of encoding ideas in a permanent form using icons and icon groups.  The act 
thereof.  Whatever.
 Underline.  A font alteration that places a line under the font.
 Unit.  A Turbo Pascal module that holds code that supports other programs.
 Var.  A compiler directive. (see variable)
 Variable.  The Pascal name given to a piece of information that may vary depending on when the pro
gram is running, who's running it or where it is in the program, etc...
 Versatile.  Capable of doing many things competently.
 Vertical.  Skew to the horizon.  Anything pertaining to up and down.  Along the Y axis.  The way a hu
man stands, normally.
 Video.  Anything pertaining to something visual on the computer system screen. (see monitor)
 Virtual.  Mostly retaining to simulated.  In computer terms, this means what you have to work with ap
pears much larger than what it actually is.  A fairly mind saving concept.  Too bad DOS doesn't have 
this feature built in.
 Virtual memory.  A technique that uses secondary storage (disk space) as an extension to primary 
storage (memory) OS/2 makes very good use of this technique to save your budget and your sanity.
 Virtual window.  A window in which the program sees much more window available to work with 
than what the user probably sees on the screen.
 Virus.  Ouch!  Dangerous snippet of code that drives fear into the hearts of men and women for that 
matter because of their very destructive behavior.  Beware of these.
 Warranty.  A agreement made as to the suitability of the product for some specific use.
 Window.  A square section of the screen that's usually framed which contains little pieces of informa
tion so that it doesn't overflow into the rest of the screen where other stuff resides.
 Windows.  Beside one of the units in the library, a graphical based DOS operating system extender by 
the Microsoft corporation that features on screen windowing and a limited form of crude multitasking.
 Word wrap.  A word processor's or text editor's ability to move words that exceed the current margins 
to the beginning of the next line automatically.  Nicely eliminates the need to use the return key.
 
Acknowledgements

 Turbo Pascal is a registered trademark of Borland International, Incorporated.
 Speed Pascal/2 is a registered trademark of the SpeedSoft company. (Vision Software)
 MS-DOS is a registered trademark of Microsoft Corporation.
 DR-DOS is a registered trademark of Digital Research, Incorporated.
 PC-DOS, MDOS and OS/2 are registered trademarks of the International Business Machines 
Corporation.
 Pentium is a registered trademark of the Intel Corporation
 WordStar is a registered trademark of MicroPro International Corporation.

@End
