home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
progm
/
m2t-1.zip
/
CHAP14.TXT
< prev
next >
Wrap
Text File
|
1989-01-18
|
14KB
|
354 lines
Chapter 14
MACHINE DEPENDENT FACILITIES
PREREQUISITES FOR THIS MATERIAL
______________________________________________________________
Before attempting to study this material, you should
understand the material presented in Part I of this tutorial
and have a clear understanding of the material on pointers in
Part II.
THIS IS WHERE YOU CAN GET INTO TROUBLE
______________________________________________________________
Modula-2 does a good job of insulating you from the underlying
peculiarities of your computer due to the strong type checking
which it does. It can prevent you from making many kinds of
rather stupid blunders simply by forcing you to follow its
predefined conventions. There are times, however, when you
wish to ignore some of its help and do something that is out
of the ordinary. If you had a need to directly interface with
some external device, you would need to get down to the nitty
gritty of the operating system and do some things that are
outside of the realm of normal programming practice.
The principles taught in this chapter can lead you directly
into the operating system where you will have more freedom
than you would have thought possible with Modula-2, but it
will place more responsibility on you. This material is only
for the advanced programmer because it will require a
knowledge of the inner workings of the computer and the
operating system. Nevertheless, it would be good for you, as
a student of Modula-2, to at least read this material, study
the example programs, and compile and run them. You will then
have a store of knowledge of these things so that you can use
them when you need them.
TYPE RELAXATION EXAMPLE
______________________________________________________________
Examine the program named TYPEREL.MOD for ===============
an example of a program with some very TYPEREL.MOD
unusual type transfer functions. Note ===============
first that three types are defined, each
being the same size considering storage requirements. The
first type is 10 integers, the second is 10 cardinals, and the
third is 20 char variables which requires the same amount of
storage as 10 integers or cardinals on most microcomputers.
If you are using a larger computer, you may need to adjust
14-1
Chapter 14 - Machine Dependent Facilities
some of these to make them the same size. The fact that all
three types are the same size is very important for what we
will do later in the program.
We begin the program part of the module by assigning the value
10 to the variable Count, a cardinal type variable. In the
next line we assign the value of Count to Index even though
they are of different types because we transform the type in
the same manner that we did back in Chapter 3 when we studied
the program named TRANSFER.MOD. Actually, we don't need the
type transformation here because integer and cardinal are
assignment compatible.
We load up the integer array named IntVars with some nonsense
data to work with, the data being the series of numbers from
65 to 74, which should be easy for you to ascertain. Then in
line 23, we copy one of the array data points to one of the
other to illustrate that the type transformation works even
on array elements.
NOW FOR THE BIG TYPE TRANSFORMATION
______________________________________________________________
In line 24 of the program we copy the entire field of 10
integer type variables into the array of 10 cardinal type
variables. The only restriction is that both of the fields
must be exactly the same size which these two are. In order
to do the transformation, the type of the resulting data area
is used in front of the parentheses of the source variables.
Line 25 goes a step farther and copies the new cardinal data
into 20 char type variables, which is permissible because 20
char variables uses the same amount of storage as 10 cardinal
variables. You could even transform a record made up of
several different types into all char variables, or all
integers, or even another completely different record. The
only requirement is that both of the groups be exactly the
same size.
This may appear to be a really neat thing to be able to do but
there are problems that you will find with this new
transformation. There are no data conversions done, only type
conversions where the data is copied byte for byte with no
concern for the meaning of each byte, which means that you may
wind up with a real mess trying to decipher just what the
transformed data means. This is called type coercion and is
simply a byte for byte copy with no concern for the meaning
of each bit in the data pattern. In addition, since each
compiler may define the various types of data slightly
different, your program will not be easily transportable to
another computer, or maybe not even to another Modula-2
compiler on the same computer.
14-2
Chapter 14 - Machine Dependent Facilities
Five of the cardinal numbers are displayed on the monitor,
then 10 of the char numbers are displayed to show you that
they really are the same numbers. The order of the numbers
may be reversed when output as individual bytes because of
the way the data is stored in the microprocessor in your
computer. This in itself is an indication that there is no
data conversion, but only a data copying, byte by byte.
One other rule must be pointed out, you cannot do a data
transformation within a function call, but it is simple enough
to do the transformation to a dummy variable and use the dummy
variable in the function call if that is necessary. This will
be illustrated shortly. Compile and run this program after
you study it.
WORD AND ADDRESS VARIABLES
______________________________________________________________
Examine the program named WORDADDR.MOD for ================
an example using some new data types. In WORDADDR.MOD
order to get down to the lowest level of ================
the machine, we need these new types, ADR,
WORD, and ADDRESS, which must be imported from the pseudo
module SYSTEM. The pseudo module SYSTEM does not exist as an
external module as the others do because the kinds of things
it does are closely associated with the compiler itself. The
designers of Modula-2 have therefore defined this module to
make these things available to us, and we import them just as
if the pseudo module SYSTEM existed as a regular library
module.
The new data type WORD is compatible with all data types that
use a single word for storage, but it is somewhat limited in
what you can do with it. It is most useful as the formal
argument to a function which can be called with any data type
that is contained in one word. In lines 27 and 28, the same
procedure is called, once with an integer type variable, and
once with a cardinal type variable. Since the procedure is
designed to handle either, it will print out both numbers by
converting them first to cardinal using the type
transformation in line 17, then calling the output procedures.
Once again, the type transformation cannot be done in the
procedure call so a temporary variable is used.
A NEW KIND OF POINTER
______________________________________________________________
The variable Peach is assigned the type ADDRESS which is also
imported from the pseudo module SYSTEM, and is therefore a
pointer to any word type of variable. Peach can therefore
14-3
Chapter 14 - Machine Dependent Facilities
point to an integer or a cardinal as is done in lines 25 and
26. The procedure ADR returns the address of any word type
of variable and it too must be imported from the pseudo module
SYSTEM.
ABSOLUTE ADDRESSES
______________________________________________________________
Notice the two strange looking variables in lines 10 and 11.
The variable MonoVideo is an array of 4000 char type
variables, but we have forced it to be located at a very
specific location in memory, namely at segment=B000(hex) and
offset=0000(hex). This is the method provided for you by
Modula-2, by which you can force a variable to be at a
specific memory location. In this case we have defined the
variable to be stored in the locations in memory where the
monochrome monitor display is stored so we can store data
directly into the monochrome monitor display area if we are
using an IBM-PC or compatible running MS-DOS.
The variable ColorVideo is the same except that the location
referenced is that area where the output for a color monitor
is stored on an IBM PC or compatible. It should be apparent
that you can gain control over the actual hardware with this
capability but it does require a lot of knowledge of the
hardware and the operating system.
In the last line of the program the variable Peach is assigned
the address of a specific location as an illustration only.
This is only possible because Peach is a variable of type
address. Your computer and compiler may use an entirely
different method of address specification than that
illustrated here. It will be up to you to study your
documentation for the details of your particular system.
It should be clear to you that with these functions, it is
possible to do a lot of data shuffling that could not
otherwise be done. The next example program will illustrate
their use further.
MORE ADDRESSING EXAMPLES
______________________________________________________________
Examine the program named ADRSTUFF.MOD. ================
This program uses the address type and ADRSTUFF.MOD
adds two new, rather simple functions, ================
SIZE and TSIZE. Actually, these are not
completely new since we used the TSIZE function in the chapter
on pointers and dynamic allocation. These two functions will
return the size in bytes of any variable or of any type. The
program on your monitor has several types defined, then
14-4
Chapter 14 - Machine Dependent Facilities
several variables, and finally initializes all of the elements
of the array Stuff to some nonsense data. The really
interesting things begin happening at line 25.
The pointer NeatPoint is pointed at the first element of the
array Stuff, and its value is dereferenced into Index. The
type transformation is required because the result of the
dereferencing is a cardinal type value. The data is written
out to the monitor. Next the size of the type IntArray is
assigned to the variable IncreAmt, which should be 8 words or
16 bytes, but may be different with you computer ans compiler.
In line 29 we do some pointer arithmetic by adding the size
of the type IntArray to the original value of the pointer
which should cause it to point to the next row of the array.
After dereferencing the pointer and getting its new value, we
print it out to find that it did indeed move to the next row
of the array. Based on the above discussion, it should be
apparent to you that you can move the pointer all around the
array named Stuff and get whatever data you wish.
The next section of the program uses a loop to continue the
process through all five rows. The only thing that may be
confusing is line number 34 where we get the size of the
BigArray type and divide it by the size of the IntArray type.
The result should be 5, and you will see that it does five
iterations through the loop. This is really a dumb way to get
through this particular loop but it is only for purposes of
illustration that it is done. Notice all of the type
transformations to integer in these statements, this is
because the functions all return a cardinal type of data.
Doing all of this in cardinal numbers would have made it much
cleaner, but this was more illustrative for you.
TWO MORE LINES OF ILLUSTRATION
______________________________________________________________
Lines 42 and 43 are given as an illustration for you of how
to use the SIZE function. It simply returns the size, in
bytes, of any variable used as an argument.
Even though we went to a lot of trouble to illustrate and
explain the pointer operations in the last program, you should
be discouraged from using this technique for software
development. In this case, you should use the usual method
of working your way through the array rather than through use
of this confusing and obscure method of using pointer
arithmetic. You will find places where pointer arithmetic
can be used to great advantage, but until then, you should
favor the use of the clear and easy to understand constructs
available in Modula-2.
14-5
Chapter 14 - Machine Dependent Facilities
PROGRAMMING EXERCISES
______________________________________________________________
1. Modify ADRSTUFF.MOD to print out some of the type and
variable sizes such as those calculated in lines 41 and
42.
2. Write a program with an array of 100 CARDINAL elements,
fill the elements with nonsense data, and use a pointer
to print out every 12th value starting at the highest
element (number 100) and working downward.
14-6