logo To Foot
© J R Stockton, ≥ 2012-09-08

Pascal Introduction.

No-Frame * Framed Index * Frame This
Links within this site :-

There is a ZIPped snapshot including these Pascal and Delphi pages (507kB+), taken on or after 2015-02-04; unZIP it in an empty directory.

Please do not fetch this page, or any other pages or files of mine, by automated subscription; that wastes my limited resources.


In May 1998, Borland renamed itself Inprise. Therefore, URLs (http://, ftp://) referring to their own sites could need a corresponding change. The newsgroup names have not changed. It seems to have reverted to being Borland.

In November 2006, I read that "Borland has announced the spin- off of it's developers tools group into a separate, wholly owned subsidiary named CodeGear."

August 2008 : CodeGear and Delphi now belong to Embarcadero Technologies, Inc.


General PC programming links are in PC Links Reference, including to "The Timing FAQ" and others by Kris Heidenstrom.

Programmers : you must get a copy of Prof. Timo Salmi's Turbo Pascal FAQ, and study it intently. I will not cover here anything that it deals with, except where I feel that an alternative point of view may help. It is a Turbo Pascal FAQ, not a Borland Pascal FAQ, but much of it applies equally to BP and TPW/BPW, and quite a bit to Delphi. Also, read the Newsgroup borland.public.turbopascal (???? Aug 2008), the Newsgroup comp.lang.pascal.borland and its mini-FAQ (c.l.p.b mFAQ), and other documents accessible via my Pascal Links pages.

Don't make a fool of yourself by asking questions for which the answers are well documented, in FAQs, newsgroups, and/or elsewhere; for example, Crt.Delay Problems, startup Runtime Error 200.

Run-time checks should all be turned ON in development, and left on whenever possible.

Target Languages

These pages are written largely for Borland Pascal 7.01, including (on the whole) Turbo Pascal & Borland Pascal for Windows. Parts will apply also to Delphi ("BP8+"), to TP<7, or to other Pascals; in particular, Microsoft Quick Pascal may have been rather similar to TP5 or thereabouts.

I myself have used only TP3, TP4, TP5, TP6, TP/BP7, TPW, BPW, D3; but now have TP1, TP3.02, TP5.5 free from Borland Museum, and TMT Pascal Demo.

I have an Amstrad PPC640 (1988), with DOS 3.3, 640kB RAM, 2 720kB FDD, no HDD, mono display; and a Tandon PacII 486/33 (1992), with DOS 6.20, WfWg3.11, 8MB RAM, various discs, colour display. Up to 2006-10-14, I had an Easi-PC clone PII/300 (1998), Win98, 64MB RAM, etc.; on 2006-10-19 it was replaced by a P4 3GHz XP sp2.

My smaller programs are generally intended to run on any of the machines, and so are compiled for the x86 instruction set; so far, no Pascal program has required the PII pr P4. Many were written on the 486. Only the PII has run Delphi; but it's now loaded on my XP portable.

I know rather little about Pascal coding for the use of Windows facilities, except with WinCrt which I gave occasionally used; though I have used Turbo Vision, and again have Delphi 3. I know little of graphics or C, and nothing of multimedia or sound cards; and nothing of programming for Networks or the Web, or of writing CGIs.

The Pascal pages comprise snippets, and are not a Pascal tutorial as such.


Coursework Questions

I normally ignore any E-mail requests or news articles from School or College students who want to have their assigned course-work or homework problems solved for them (including project selection). I may advise on specific points of difficulty, which will require evidence of thought having already been devoted to the problem; or I may correct errors in subsequent news discussion.

I know little very little about the formal teaching of computer languages.

I suggest that learners without college affiliation should indicate their circumstances....

Other Questions

To save wasting time, don't even think of asking me about networking or multimedia or graphic/adventure games or window handling or other languages. Or downloading pirated software. For legitimate software, see Pascal Links, Page 1.

Moreover, I do not supply missing parts of commercial software: (a) that is something that the original supplier can legally do, and no-one else; (b) I am on a dial-up connection, charged by time.

Don't ask me elementary questions such as are covered by any introductory textbook or tutorial.

Don't send E-mail in anything other than plain text, single copy, concise. No HTML, no MS Word, etc.

Don't repeat News posts in E-mail to me, verbatim or otherwise.

Those with real names and respectable accounts are more likely to get questions thought about or answered.

General Pascal Information

Operating Systems

I know very little about systems other than (RT-11 and) DOS 3.2 to 6.20 and Windows 3 to Windows for Workgroups 3.11 and Windows 98. However : Long File Names.

File Types

In MS-DOS, there is no such thing as a Text file or a Binary file; if there were, there would be an Attribute bit for it, since there were at least two bits spare originally. A file is a file is a file. It consists of as many bytes/characters as the directory entry says.

Some files are often best treated in a special manner by DOS, with an ^Z being a terminating character (maybe only if in the last sector or last 128 bytes). This is done to support an older convention (CP/M?) where the directory entry did not give the exact number of bytes and so a free-format file needed a terminating character/byte.

This convention was used for files which were intended to be interpreted basically as lines of characters with newlines (of whatever form) where required. As this is generally useful, many quite independent programs support the text interpretation of a file, with or without ^Z.

Other files are of other formats (in the case of some data files, of "no" format) - these formats can only be handled by the programs/systems which "own", "clone", or "borrow" the format. Some of these formats are proprietary, some are invented by standards bodies, some have evolved.

Some text files have further "formatting" within the lines - e.g. HTML, Pascal.

Any file can be opened as a text file, a typed file, or an untyped file; whether each of these makes sense depends on whether the operations done with the file are appropriate to the mode of opening. For example, a file intended to be used as text (such as this message will be stored as, on many but not all systems) can be opened as a "file of char" or as a "file" in order to copy it, split it, truncate it, or do character/byte distribution counts.

Starting and Finishing a Program

Frequently I begin my programs (and units with initialisations) with a Writeln(<name>[more]) ;, so that I can at least tell that they have really started running. A test program may conveniently be ended with Write('<cr>') ; Readln ; to save using Output or Alt-F5 in the IDE.

The general intention of any program or unit should be obvious on once looking through the source file; it should contain both detailed comment where needed within the program and overall comment (or writes) saying what it is basically supposed to do.

Program Layout

There are many views on Pascal program layout. It is generally agreed that, within any structure such as begin..end, repeat..until, and on continuation lines, the indentation should be increased by 2..4 spaces.

Some programmers like to put a newline wherever possible; others do not. I myself prefer to put more than one statement on a line where they are closely related :-

with Point do begin x := 0 ; y := 0 ; z := 0 end {Point} ;

My style can be seen in the programs directory.

It seems to me that a good test project for a new programmer would be to write a program in Pascal to re-indent a Pascal program or unit according to personal preference, and to install it as a Tool; my CLEAN-TP.PAS suits my needs. While I am programming, all that I need to do is to type Alt-T T to process the contents of the current Editor window. Even though the "partial parsing" in the program was written for ease rather than efficiency, the process is sufficiently fast that there is no need to indent correctly when typing in. Subsequent incorrect indentation indicates the location of the common "missing end" error better than the complier error message does. (Others may prefer to use Ed's Pascal Beautifier, or other programs.)

Identifier Names

Identifier Names should be reasonably short yet reasonably meaningful, depending in part on the number of lines of source that they're in scope for. Where a variable is used only locally, for a simple and obvious purpose, I see no need for it to be more than one or two characters long.

One should never choose names in a program such that there is significant visual ambiguity in any normal font. This is particularly important for any material that may be distributed or publishes, especially electronically.

Do not use, under any normal circumstances, O or l, because these can be too readily confused, especially in a fixed-width font, with digits 0 and 1 respectively - O 0 l 1. Avoid other cases where such confusion matters; and remember that while Var1 & VarL look distinct, Varl will look to you like the first and to the compiler like the second.

Do not wantonly redefine the name of any well-known component of any library.

Uses of Type Casting

If, in COMMON.PAS, you have

type FOURBYTE = record case byte of
    1: (LI : longint) ;
    2: (W12, W34 : word) ;
    3: (I12, I34 : integer) ;
    4: (X : byte ; W23 : word) ;
    5: (Y : byte ; I23 : integer) ;
    6: (B1, B2, B3, B4 : byte) ;
    7: (S1, S2, S3, S4 : shortint) ;
  end ;

then "HighX := FOURBYTE(X).W12 ;" will extract the top word, should compile to the same code as the simplest "asm..end", and is readable Pascal once one recalls FOURBYTE. This is much better than "HighX := X div 65536 ;" or "HighX := X shr 16 ;" One can also do things like "XXX := Sqr(longint(FOURBYTE(X).S1))".

General Base Conversion

There are two ways (at least) of converting a number from a source base to a destination base; one uses arithmetic in the source base, the other in the destination base. If there is a "natural" base in the system, it may be best to do arithmetic using it, even if that means a two-stage conversion, such as base 3 to decimal, via internal binary.

An example would be for a person converting between base 10 & base 7; few of us are good at base 7 arithmetic, but most recall base 10.

To convert TO base 7, take the integer, divide by 7, using the source base; the remainder is a base 7 digit, and the result, if greater than zero, is used in the same way to generate preceding digits.

To convert FROM base 7, start with a result of 0, and at each successive stage, using the destination base, multiply the result by 7 and add the next digit, until done.

Do NOT bother with a table of powers of 7 to base 10, or vice versa; that is a cumbersome method, and ought (untested) to be slower.

The multiplicative way, for converting between any base in 2..16 and any other such base, is buried deep in my program longcalc.pas; routine ConvBas contains calls of Times and Plus.

See baseconv.pas (under-tested : 2000-09-13, also as Filter, 2002-01-22, with ZIP).

Binary String Conversion

This applies, more or less, to other bases too. Many people calculate the value of each bit position, multiply by the digit value, and add; it's amazing how often the simple " * base and add " loop is missed. This (lightly tested) appears to work for all 32 bits.

function Bin2longint(const S : string) : longint ;
var tmp : longint ; p : byte ;
begin tmp := 0 ;
  for p := 1 to Length(S) do
    tmp := tmp shl 1 { generally, tmp:=tmp*BASE} + Ord(S[p])-Ord('0') ;
  Bin2longint := tmp end {Bin2longint} ;

SHL gets around range checking; I suspect that *BASE would not.

Conversion to Lower Case

If you already have function UpCase(Ch : char) : char ; defined, whether it be the standard Borland one or any other (possibly adapted for a language other than English), then you may want the inverse operation, assuming that there is one. The following costs a little setup time, but should reliably give a lookup table for the inverse of any UpCase function, provided that there is a 1:1 correspondence between the two cases :-

var array LowerCase [char] of char ;
for C := #0 to #255 do LowerCase[C] := C ;
for C := #0 to #255 do
  if UpCase(C)<>C then LowerCase[UpCase(C)] := C ;

You may also generate the table array UpperCase [char] of char ; likewise.

Bad Pascal

The following illustrates some constructions (Reminder : Turbo or Borland Pascal sometimes assumed. These are probably also Bad Delphi) often seen in use, with preferred (by me) replacements, generally on grounds of clarity; the central symbol compares the code sizes in BP7.

# BAD Pascal = GOOD Pascal
1 IF RelExp
 THEN BoolVar := true
 ELSE BoolVar := false ;
> BoolVar := RelExp ;
2 IF BooVar=True THEN ... ;
IF BooVar=False THEN ... ;
= IF BooVar THEN ... ;
IF NOT BooVar THEN ... ;
3 IF RelExp
 THEN Thing := Long Expression
 ELSE Thing := Similar Expression ;
> Thing := Long Expression ;
IF not RelExp THEN Amend Thing ;
4a IF x AND $20 = $20 THEN ... ; = IF x AND $20 <> 0 THEN ... ;
4b IF x AND $20 = $20 THEN ... ; ? IF Bit5 in BitSet(x) THEN ... ;
5 (* B being constant *)
Q := (A and (1 shl B)) > 0 ;
> Q := BitB in BitSet(A) ;
6 FOR k := 65 TO 70 DO P(char(k)) ; = FOR ch := 'A' TO 'F' DO P(ch) ;
7 CONST Pi = 3.14159 ; - (* Pi is predefined, exactly! *)
8 ... . ...

Remember that boolean, char, and enumerated type variables can be used in array declarations, as the control variables in for loops, and in case statements.


(This may be a bit compiler-specific) To be validated :-

A normal Boolean is stored using an 8-bit byte, and ISTR pre-defined as type boolean = (false, true) ; so that Ord(false)=$00 and Ord(true)=$01. Between if and then, $00 is taken as "false" and anything else as "true".

ISTM ... Also, the operators and, or, xor, when acting on booleans, operate on the "truth" interpretations, and provide a result whose bit-pattern is either $00 or $01.

But the cast boolean() does not change the bit pattern, and I guess that both of the following expressions evaluate to "true" :-

17 <> not 17
boolean(17) = boolean(not 17)

In TP7/BP7, provided for Windows compatibility, WordBool is 16 bits and LongBool is 32 bits.

Text-Mode Cursor

In different video modes, the cursor uses different scan-lines; and some programs change the appearance to indicate overwrite/insert mode. To hide the cursor, read the settings with Int 10/03, set bit 5 in CH without changing the other bits (CH := CH or $20), and call Int 10/01; to restore it as it was, clear bit 5 likewise (CH := CH and not $20). See TSFAQP, item #21, for a discussion, including MDA and Hercules differences; also #156 (in draft, 2000-10-28).

The following are from SHOWER; I forget why I set CX to $2000 - perhaps because on some systems setting bit $20 of CH does not work. I also forget why I used S.

procedure TShower.NoCursor ;
var S : word ;
begin asm mov AH,03h ; mov BH,0 ; int 10h ;
    mov S,CX ; mov AH,01h ; mov BH,0 ; mov CX,2000h ; int 10h end ;
  CurSize := S end {TShower.NoCursor} ;

procedure TShower.CursorOn ;
var S : word ;
begin S := CurSize ;
  asm mov ah,01h ; mov bh,0 ; mov cx,S ; int 10h end ;
  end {TShower.CursorOn} ;

Setting the start line after the finish line gives an inverse cursor on some systems, and a blank on others.

An "arrow" (or other graphic) cursor can be made in text mode by redefining the glyphs for four characters not otherwise required on the page, and substituting the characters for those around the location.

Re losing cursor after Exec in TV, see APP.PAS DosShell.

Delphi may have ShowCursor(boolean).

Text, Blink or Background Bright

Setting the MSB of the Attribute byte of a displayed character makes it either Blink or Background Bright. To determine which (for the whole screen) :-

procedure BrightBack ;
begin asm mov AX,1003h ; mov BX,0000h ; int 10h end end {BrightBack} ;

procedure Blinking ;
begin asm mov AX,1003h ; mov BX,0001h ; int 10h end end {Blinking} ;

Note that these did not work in a Windowed WfWg3.11 DOS box, but were OK full-screen.

Certain Microsoft DOS software alters and does not restore the blink/bright state.

Blink is a hardware function, and therefore not available in a Windows DOS box, unless full-screen.

My Programs

These should all be immune to the Crt unit RTE200 bug.

Index to my directory of utility and demonstration programs.


Utility programs are present as *.PAS, *.EXE, and in some cases *.TXT, and as *.ZIP containing those.


Demonstration programs are present only as *.PAS files.

Some Simple Games

Some silly text-mode Turbo-Pascal 5.0 computer games (CONNECT4, BOXES, GAME, PATIENCE, GIBBON), in *.PAS and *.EXE form; these were produced, in TP5, by myself with various young people, as a combination of Christmas-time amusement, demonstration, and programming practice. Patience is Solitaire; Game resembles the BBC computer underwater arcade game; Gibbon is "inspired" by MS-DOS GORILLA.BAS; Boxes is well-known; Connect4 is "Connect 4". For instructions, read the comment in the *.PAS, read the screen, and think. By preference, they are mostly controlled with the numeric keypad, and may be left by <Esc>.

N.B. Because of the way and date that these were written, they are not offered as particularly good examples of Pascal coding.

Wirth's Pascal

Scott A Moore hosts a copy of Niklaus Wirth's Pascal-S, adjusted for current machines.


Mo - Mega-Octets (Fr).

Home Page
Mail: no HTML
© Dr J R Stockton, near London, UK.
All Rights Reserved.
These pages are tested mainly with Firefox and W3's Tidy.
This site, http://www.merlyn.demon.co.uk/, is maintained by me.