[Back to TUTOR SWAG index]  [Back to Main SWAG index]  [Original]

                       Turbo Pascal for DOS Tutorial
                           by Glenn Grotzinger
                          Part 14: The CRT unit.
                copyright (c) 1995-96 by Glenn Grotzinger

Hello.  Here is a solution from last time...

{$M 65520,0,655360}
{$B+}
program part13; uses dos;

  var
    drive, s: string;
    drivesize: longint;
    thefile: text;

  function number(n: longint): string; forward;

  procedure listdirsizes(filedir: string);
    var
      size: longint;
      f: string;
      dirinfo: searchrec;
    begin
      size := 0;
      f := filedir + '\*.*';
      findfirst(f, $27, dirinfo); { allfiles - VolumeID - directory }
      while doserror = 0 do
        begin
          size := size + dirinfo.size;
          findnext(dirinfo);
        end;
      writeln(thefile, filedir, number(size):50-length(filedir));
      drivesize := drivesize + size;
      findfirst(f, $10, dirinfo);
      while doserror = 0 do
        begin
         { for some reason, the findfirst above doesn't work right. }
         { Unable to determine exactly why...:<                     }
          if (dirinfo.attr = $10) and (dirinfo.name <> '.')
             and (dirinfo.name <> '..') then
            begin
              s := filedir + '\' + dirinfo.name;
              listdirsizes(s);
            end;
          findnext(dirinfo);
        end;
    end;

  function number;
    var
      i, j: integer;
      s, r: string;
      m: integer;
    begin
      str(n, s);
      r := '';
      i := length(s);
      if i > 3 then
        begin
          while i > 3 do
            begin
              for j := i downto i-2 do
                r := s[j] + r;
              r := ',' + r;
              i := i - 3;
            end;
          for j := i downto 1 do
            r := s[j] + r;
          number := r;
        end
      else
        number := s;
    end;

  procedure writehelp;
    begin
      writeln('Include a drive like this: c:');
      halt(1);
    end;

  begin
    assign(thefile, 'FILESLST.TXT');
    rewrite(thefile);
    if paramcount <> 1 then
      writehelp;
    drive := paramstr(1);
    if (length(drive) <> 2) or (drive[2] <> ':') then
      writehelp;
    drive[1] := upcase(drive[1]);
    writeln(thefile, 'Drive: ', drive[1]);
    listdirsizes(drive);
    writeln(thefile, '===============':50);
    writeln(thefile, number(drivesize):50);
    close(thefile);
  end.

In this part, we will try to discuss the complete usage of the CRT unit.
The CRT unit will allow with text different things, such as PC speaker
control, control of the screen for screen clears, positioning of the
cursor, changing the color of text and background, and so forth.

Basically, when the uses crt, or wincrt, is used, direct writes to the
screen are initiated, and can not be redirected to text file.

Boolean variables.
==================
There is a list of boolean control variables accessible through CRT.

CheckBreak.  It is true by default. If it's false, CTRL+BREAK will be
unfunctional.

CheckEOF.  It is true by default.  If it's false, CTRL+Z when pressed
will not represent an EOF in the program.

CheckSnow.  Enables and disables "snow checking" on CGA adapters.

DirectVideo.  Enables and disables direct video writes.

Keypressed.  Will return true if a key has been pressed.  Usable in a
loop for doing something until the user stops it.  A function like this
is similarly used for example in screen savers to stop the display.
Here is a small example to see how it acts.

program the_key_pressed; uses crt;
  begin
    repeat
      write(#254);
    until keypressed;
  end.

This program should write ascii character #254 to the screen repeatedly
until the user presses a key.

Screen Manipulation Commands
============================
Clreol;  Clears to the end of the line for the currently active window
from the current cursor position.  The concept of "currently active
window" will be explained later.

Clrscr;  Clears the screen.  Already used and demonstrated.

Delline;  Deletes the current line containing the cursor.

Insline;  Inserts line at current position.

PC Speaker Sounds and Machine Delay
===================================
These are the basics of controlling the PC Speaker to make sounds.
The first thing is that there is an ASCII character #7 which will cause
a standard DOS PC Speaker beep.

Then there are some pascal procedures which will offer much more control.
You will have to experiment with it using different numbers in the delay
and sound value.

Delay(milliseconds: word); will delay the program for approximately the
number time in Milliseconds.
Sound(hertz: word); will start up the PC speaker at a specified frequency.
NoSound; will stop the PC speaker.

Here is an example of use of the PC speaker through TP.

program test_of_pc_speaker; uses crt;
  begin
    sound(1500);
    delay(500);
    nosound;
  end.
Basically, we're emitting a sound of 1500 Hz, for a time of .5 seconds.

Note: The delay procedure can be used anytime to "freeze" up the system
for a specified period of time, say if we want to delay between writes.   

Screen Positioning
==================
These is a command to control positioning of writing on the screen.

gotoxy(x, y); is a procedure that will position the cursor at the point
defined by x, y.  The standard defintion of the screen positioning is
a cartesian system like this for the standard video mode (on most systems
when you boot them up).

(1, 1)(2,1)----------------------------------------------...  (x, 1)
(1, 2)
  |
(1, 4)
  |
  |
  |
  |
  |
  |
 ...
(1, y)

x and y is defined by the current video mode, which is settable.  We will
discuss how to set the current video mode.   The standard video mode at
bootup is 80x25.

wherex is the current x position of the cursor, while wherey is the current
position of the y variable.  gotoxy(wherex, wherey+1) is valid as an
example, and will move the cursor DIRECTLY down one unit, irreguardless
of where it is (as long as x and y are valid, most of these commands are
inactive if they get bad data)

The view window can also actually be changed.  The window function can
be used for this purpose.  The window is measured by the coordinate of
the upper left hand corner of the window (x1, y1), and the lower right
hand corner of the window(x2, y2).  The syntax if we call window is
window(x1,y1,x2,y2);  This is one procedure that you really need to
experiment with to see its effects.  As a note, most, if not all of the
screen writing commands are affected by this window...

Changing Text Color, Appearance, and Mode
=========================================
These are functions and procedures which control the appearance of text.

HighVideo; will select high intensity characters.
LowVideo; will select low intensity characters.
NormVideo; will select the original intensity at startup.

Textcolor(color); and Textbackground(color); are used to control the
foreground and background color respectively.  Foreground colors
work from 0-15 and the background colors are from 0-8.  Blinking
foreground text adds 128 to the value.  A list of text color constants
which are equated with these numbers can be found on page 192 of the
TP programmer's reference.

LastMode is a word variable which will hold the current video mode that
the system was in when the program started execution.

Changing text mode actually involves changing what x and y as was originally
stated in the description of gotoxy.  textmode(modeconstant); actually
does this.  As with everything in this part, you should experiment with
all of the commands and procedures defined, because you can't exactly
be showed the effects of these commands in this tutorial.  A list of
mode constants can be found on page 26 of the TP programmer's reference.

Here is a sample program which demonstrates several of the functions and
procedures listed, and gives us an idea of what can be done with
manipulation of text windows, colors, and so forth.  Be sure to run this
one, and experiment with changing some of the values and actions to see
what happens.

program demo_of_fun_text_manipulation; uses crt;
  var
    oldx, oldy: byte;
  begin
    { save original position of cursor so we can return there later }
    oldx := wherex;
    oldy := wherey;

    window(2,2,20,20);
    textbackground(Blue);
    clrscr; { blue background now b/c blue when clrscr was called }
    highvideo;
    window(10,10,15,15);
    textbackground(Green);
    clrscr;
    textcolor(LightCyan + blink);
    write('Hello, how are we doing today?');
    window(1,1,80,25);
    gotoxy(oldx, oldy);
  end.
Reading Characters from the Keyboard
====================================
You may have been wondering, how to directly read things from the keyboard.
The CRT offers a function called readkey, which is a parameterless function
that returns a character.  Unlike read or readln, it does not require a
CR to initiate.  You may see this by replacing a character read from the
keyboard somewhere in your program with something like this:

                answer := readkey;

You will notice that you did not have to press ENTER to move on.  Also,
you will notice that the character didn't echo.  Very useful for password
applications.

The next advantage of readkey is that it can be used to read about every
key or key combination on the keyboard.  For this tutorial, we will discuss
simply the keys that can be accessed via one keypress using a basic standard
to be discussed in the next paragraph.

Extended keys, like the function keys, or the arrow keypad may be read
using readkey.  These keys generate a #0 character as their first character
followed by an extended scan code.  These vary depending upon which key
is depressed.  To read extended keys, we would have to use a structure
such as this:

            char := readkey;
            if char = #0 then
              char := readkey;

Most of the one press keys on the keyboard may be detected using this
method.  Examples of those keys which can't be detected using the
method described by the snippet of code above are the shift keys,
capslock, ScrollLock, NumLock, F11, F12, the CTRL keys, and the ALT
keys.  There are other methods available for those keys and key comb-
inations.  I recommend as practice that you set up a reader program that
will tell you what the extended character codes are for each of the
extended keys (any key not on the basic keyboard).

Practice Programming Problem #14
================================
Create a program in Pascal and entirely Pascal that will do the following:

1) Using normal text mode, set up a screen that has a green background
all the way around the screen as a frame of 4 units in size all the way
around.  Inside of that, place a red frame of 1 unit all the way around.

2) Inside all of the frames described in part 1, set up a title that
states "Keypress Detector" on the first line available below the red
frame, in an high-intensity light cyan.  Be sure this title is NEVER
overwritten by scrolling text.

3) The "Keypress Detector" title should be on a black background.  Also,
the text which shows what keys we have pressed are should be a dull
lightblue on a black background.  The exception to the last statment is
that any standard key identity in the statement should be in a bright
green, and any extended key identity in the statment should be in a
bright red.  Key identity will be evident as I give a sample.

(properly inside the "frame")

Keypress Detector (press ESC 5 times to terminate)
You pressed the F1 key.
You pressed the SPACE key.
You pressed the LEFT key.
You pressed the Backspace key.

Note: Some of the keys on the keyboard are singular control characters.
Look at your ASCII chart.  For example, the TAB key is actually ASCII
character #9, and character #9 should be recognized as such...

F1, SPACE, LEFT, and BACKSPACE are the key identities as I described
earlier...

4) Make sure that in order to terminate the program, the ESC key gets
pressed 5 times, not consecutively (be sure to indicate the ESC key has
been pressed each time).  Upon termination, the entire screen should
visibly scroll up until none of what we wrote is visible anymore (clue:
use delay).

Next Time
=========
We will discuss the usage of the QuickSort and ShellSort algorithms.
Please by all means send comments to ggrotz@2sprint.net.


[Back to TUTOR SWAG index]  [Back to Main SWAG index]  [Original]