Skip to main content

All that I have said may discourage you.
It is such a long way from steps to true dancing.
It is, but you should not be discouraged.

Arnold L. Haskell- The making of a Dancer.


part fourteen


Long ago - almost two years when I think it over - thus in the
beginning of this course, I spent a word or two on FORTH and the
problem of arithmetic with floating- point numbers. Till now we
only used integers when we had to do some calculations. We even
avoided the problem of single and double length integers and the
appropriate operators. We assumed, that our FORTH used a non-
83-standard parameterstack of 32 bits, that all integers were of
the corresponding length and that operators were designed to act
on 32 bits integers only. And I told you, that FORTH is basically
not much good for solving arithmetical problems. FORTH isn't
quite well trimmed in this respect. The inventor of FORTH,
Charles Moore, did not create a computerlanguage just for the
reason of solving mathematical and arithmetical problems. Of
course, FORTH allows you to do the basic arithmetical movements:
subtraction, addition, multiplication and division. But for
calculations involving sinus, cosinus, tangens and the like FORTH
does not supply any specific tool. Some BASICs are very well
equipped in this regard. OMIKRON BASIC for instance provides a
basket full of arithmetical and mathematical operators to meet
with the most sophisticated demands. FORTH does nothing of the
kind. Furthermore, FORTH even doesn't have the possibility to do
floating point arithmetic. Bear it in mind: no bunch of opera-
tors, no possibility to do floating point arithmetic.


So if programming a computer involves mathematics, I just better
forget to do it in FORTH ? Wait a second. I didn't say that. You
know the Kitt Peak National Observatory in the U.S.A. ? This
observatory does a lot of research in the field of spectral
analysis of the light of stars (especially infrared sources).
Most of the work is fully automated and computer controlled,
including an extraordinary accurate telescope, the dome etc.
Applications of this type often make use of Fast Fourier and
Walsh Transforms and numerical integration. And a lot of other
math routines. Here they all are written in FORTH. Again it
becomes clear, what exactly is the basic solution that FORTH
provides for the compromise between man and computer. It is of
course very convenient for the human user of a computer to have
lots of math-operators at hand to solve adequate problems. But it
is not said, that the overhead of operators is compatible with
the internal operation of a computer. The main reason we invented
computers and use them is their speed in handling complex
arithmetical operations without getting tired. If you demand
speed, then at first you better have a language that you can use
to create a problem-oriented solution. If you want to cross a
lake, you can swim of course, but you could do it equally well on
boat or even with an aircraft. But when you have decided to swim,
there is no need to drag a rowboat and a plane with you as well.
They won't help you to swim faster, they will act more as a
handicap than that they will be of any help. As a language FORTH
provides you with a powerful set of standard commands and the
mechanism by which you can create your own commands. This
mechanism lets you build new definitions upon older ones in a
structured way and secondly, it has the possibility of defining
words directly in assembler mnemonics with the help of the
FORTH's assembler. So you can create your own math operators, as
much as you like and of the kind you need. So the absence of pre-
defined math operators will not obstruct the use of them, as you
can define them yourself. Wait and see, in a while we will give
an example of two self-defined operators called sinus and cosinus
by which you can draw a circle.

But, you are likely to remark, a sinus-operator will force you to
use floating point arithmetic. And you just told me that FORTH
isn't equipped for that job. Well, here follows my answer to your
intelligent observation. We aren't to go to use floating-point
arithmetic at all !! In part three we spent some words on
floating-point and fixed-point arithmetic. We are going to dig
deeper here and now. First we have to answer two questions: what
are floating-point and what are fixed-point numbers in relation
to a computer. I assume that you know what floating-point numbers
are and what purpose they serve in all day life. In common
arithmetic a floating-point number is written to represent a
broken quantity: 3.1416 for instance is the floating-point
representation of ?. Now you will have to accept the fact that
internally a computer cannot 'write' the number ? in the same way
we are used to do this on a piece of paper. Internally a
computer can only store numbers as integers: 33, -4456, 1, 879
etc. So to store floating-point numbers a computer uses a form of
scientific notation. The common way of writing 17 million on a
piece of paper is 17,000,000. (Europeans, watch out, I am using
the American notation; it uses comma's where as Europeans use
points and points where as Europeans use comma's). In scientific
notation 17 million is written as 17 X 10^6. Ten to the sixth
power equals 1,000,000 ( 10 X 10 X 10 X 10 X 10 X 10 ). And 17 X
1,000,000 equals 17,000,000. To store 17,000,000 in a computer we
could store two characteristic numbers: 17 and 6. Hereby it is
understood that 6 is the power by which ten has to be raised and
that this result has to be multiplied by 17. The number ? is
stored as 31,416 and -4. Ten to the power -4 equals -10,000 and
31,416 multiplied by -10,000 equals 3.1416. So two relatively
small numbers can represent an enormous range of numbers, from
atomic to astronomic. In Omikron Basic this method allows the
storage of numbers in the range of +- 5.11 times 10 to the power
of 4931. And it consumes only 10 bytes pro number. Amazing, isn't
it ? So now for the fixed-point representation of numbers. In
fact there isn't such a thing for a computer as a particular way
of representing fixed-point numbers internally. Internally
numbers used in fixed-point arithmetic are represented as plain
integers. Using a 32-bit computationstack (or double numbers with
a 16-bit stack) numbers can range from plm. -2 billion till plm.
+2 billion. So the largest number has 10 digits as its maximum ,
regardles if there is a decimal point or not.


Fixed-point arithmetic demands for a certain way of numberhand-
ling in calculating arithmetical and mathematical expressions.
This way is called 'scaling'. All numbers used in an expression
must conform to the same "scale". That is, all decimal points
must be in the same place. The decimal points are not actually
present. As an example let's observe both the fixed-point and
floating-point representation of meters, centimeters and milli-

A carpenter's notationFixed pointFloating point

1 m 36 cm 5 mm 1365 1365 -3
11 m 45 cm 11450 11450 -3
6 m 02 cm 6020 6020 -3
1 m 1000 1 3

A carpenter writes it down as it is done in real life. In fixed
point, all measures are scaled down till all can be named with
the same name i.c. millimeters. In this way the decimal point
can be properly aligned (in the third place from the right)
although it is not actually present: internally, as said, the
computer treats the numbers as integers. It isn't but at the
moment of sending readable output to the screen or printer, that
a "correct" answer is performed by inserting a decimal point in
the right place. Now I have a simple question. If you had to add
one of the three kinds of number- representations above, which
one would you prefer ? No doubt it will be the row with the
fixed-point numbers. And what do you think will be the answer to
the second simple question ? Why did you prefer the fixed-point
numbers ? Because you can take in everything at a glance. So this
addition will be the simplest and thus the fastest of the three.
Arithmetic with fixed-point numbers is compatible with the
internal operation of a computer 'in optima forma'. This is the
way to gain the maximal speed. But what, if the result should
have been expressed in meters and not in millimeters ? Well, then
you would have had to remember, where you had to insert a
decimal point. Or rather in case of a computer-program, you
should have let known the computer program where it should
insert a decimal point when it had to output the result.


So principally we can solve the two problems, that seemed to
obstruct the use of advanced mathematical calculations in FORTH.
The lack of standard words can be substituted by defining
operators of your own. The absence of floating-point numbers can
be overcome by using fixed-point numbers. Both solutions imply
quite some knowledge of scaling techniques, rational approxima-
tions, a deep insight in arithmetic and a lot of programming
ingenuity. If you are going to write an application which must
meet high mathematical standards, then the use of fixed-point
arithmetic will require an extra amount of thought. You cannot
write an application involving 'high' maths in any computer-
language whatsoever, without knowledge of the subject you will
bring up, can you ? Let's face it frankly. A computer cannot
elevate the level of a person's capabilities. The level of a
person's capabilities determines the level on which the computer
will perform. A bad play with a master-director will have more
chance to succeed than a good play in the hands of a sucker. But
normal intelligence will do for most of the jobs we like our
computer to do. So you can avoid floating-point arithmetic, if
your system lacks floating-point operators and does not admit the
use of floating-point numbers. Remember the Big Four you will
need to accomplish this task: Scaling techniques, Rational
approximations, Deep insight in maths, Programming ingenuity.


Let's be practical and give an example of a scaling technique.
The other day my wife got the idea of doing some crotchwork: a
tablecloth. The question arose, how many kgs this piece of home
handicrafts would weigh, when (and IF !!) she would have finished
it. Our dining-room table measures 2.12 m X 0.965 m and that's
quite a big one...and heavy too !! To get a nice looking table
when the cloth covers the table, it should exceed this measures:
2.62 m X 1.26 m would do fine. A ball of cotton weighs 50 grs.
One ball suffies for an area of 13.5 dm2 of crotchwork. Now we
have all that we have to know to calculate the weight of the
future tablecloth in kgs. To do this in fixed point arithmetic,
we have to scale down the measures of the tablecloth to
centimeters: 262 and 126. Now we can calculate the area

262 126 {*} {.} 33012 OK

This result even fits in a 16 bit integer. To get the number of
balls, we have to divide 33012 cm2 by 13.5 dm2. So we again have
to scale down to cm2: 1350 cm2. The calculation now will show

33012 1350 {/} {.} 24 OK


But...24 balls will not do, as we did not count for an eventual
modulo as a result of the division above. Even if the modulo
would have been 1 cm2 - it is 602 to be precise -, we would have
to buy 1 ball of cotton extra. How to solve this problem, that
obviously is connected with rounding and truncating of numbers ?
Well, we will have to add 1349 cm2 to the area of our tablecloth,
to be sure, that when a modulo - any modulo - occurs as we divide
the area of the tablecloth by the area of one ball of cotton, we
always will get one ball extra. So we can write

33012 1349 {+} 1350 {/} {.} 25 OK

And now we will be able to buy sufficient material for my wife's
crotchwork. Remember we want to know the weight in kgs. Our
little program will have to display that result at the screen.
First we

25 50 {*} {.} 1250 OK

to calculate the weight of 25 balls each weighing 50 grs. As we
are going to change grs into kgs, we will have to insert a
decimal point three places from the right. At the screen the
result must look like 1.250 kgs. We did some exercises on
numberformatting, remember ? We used {<# } and {#>} and more of
these numberformatting words. We will define

: .KGS <# # # # 46 HOLD #S #> TYPE SPACE ."kgs." ; OK

Now we again

25 50 {*} {.KGS} 1.250 kgs OK


Marvellous, isn't it ? We have used fixed point arithmetic
without loosing accuracy. Suppose our table wasn't a rectangle
but a circle. There is not a FORTH-word called {PI}. As you
probably will know, you need a constant called pi and written ?,
to calculate the area of a circle. The constant ? is approxima-
tely 3.1416. The area of a circle with a radius of 10 cm is
calculated as 10 X 10 X 3.1416 in floating-point ( the formula is
?r²). We could write this down as 10 X 10 X 31416 : 10000 and get
the same result. You see, we substituted the floating-point
number 3.1416 with a so called rational approximation in the form
of 31416 {*} 10000 {/}. The word 'rational' points to the fact,
that the approximation of the value of ? is made with the
exclusive help of rational numbers. These rational numbers are
always whole numbers or a fraction in which the numerator and
denominator are both whole numbers. The following are all
rational numbers: 3, 12345, -123, 2/3 and even 3.1234. The number
2/3 is a rational number because it can be written as 2 3 {/}
and 2 and 3 are rational numbers; for the same reason 3.1234 is
rational (31234 10000 {/}). But 3?2 is not a rational number. It
is irrational. Almost all irrational numbers can be replaced by a
rational approximation. The constant ? is irrational, because the
part of ? beyond the decimal point can be repeated endlesly. For
the sake of practise we often use a rounded value of ?, 3.1416 or
with more or less digits beyond the decimal point depending on
the level of accuracy one wants to achieve. But 3.1416 is a
floating-point number, we weren't going to use them. So we
propose to use the rational approximation 31416 {*} 10000 {/}. It
gives us an accuracy to four places beyond the decimal point. But
there is a pair of numbers that reaches for more. Here it is: 355
{*} 113 {/} , which is accurate to more then 6 places beyond the
decimal point. The definition of ? is then written as

: PI 355 * 113 / ; OK

The area is then calculated as

10 {DUP} {*} {PI} {.} 314 OK

Or still better

: AREA DUP * PI . ; OK

Now we can calculate areas of circles with our self defined
mathematical function {AREA}. Suppose our round table has a
radius of as much as 1 m. Then we could calculate the area like

1000 {AREA} 3141695 OK

(1. The number 1000 stands for a thousand millimeters = 1 m.)
(2. You might have wondered, why I didn't use {*/} in the
definition of {PI}. The answer is simple. In a 16 bit FORTH the
use of {*/} truly is far more efficient than the use of {*} and
{/} separately. This is due to the fact, that the result of the
multiplication part of {*/} is stored as a 32 bit integer, a
double number. In the 32 bit FORTH I use mostly, there isn't any
difference. In both cases the result of the multiplication will
be stored as a 32 bit integer, and not as a 64 bit intermediate
result with {*/} in the 32 bit FORTH. In case you have a 32 bit
FORTH which stores the intermediate result of {*/} as a 64 bit
number, you should use {*/}, of course).

The rest of the calculation to get the weight of the tablecloth
is simple. Watch out, we got the area of the circular cloth in
quadratic millimeters to achieve the maximum accuracy of six
places. So we will have to scale down the area that can be done
with one ball (13.5 dm2) to mm2, that is 135000 mm2. Having done
that we can do

3141695 135000 {/} {.} 23 OK

If we would have typed

3141695 13500 {/MOD} {.} {.} 23 33695OK

we would have noticed, that the modulo of 33695 indicates that we
should have rounded up. So

3141695 134999 {+} 135000 {/} {.} 24 OK

will deliver us the right number of balls we will have to buy.

You should have learned another important item, while studying
the above example. There seems to be a annoying competition among
various dialects of BASIC, each fighting to have the most digits
beyond the decimal point in their floating-point numbers. But
will you ever have to buy 3.435465787654434239 balls of cotton,
pencils or Heaven may know what ? In real live we mostly will
have to deal with whole things or if there has to be a fraction,
we will like to minimize the digits beyond the decimal point for
various reasons: readability is one of them. Humans don't like
large numbers, it frightens them. We don't speak about 4096
bytes, we say 4 kilobytes, and we transform 4096 Kb into 4
megabytes and furtheron they become gigabytes. The units the
numbers denote grow, the numbers themselves stay small, so they
won't cause an overflow of our imagination. Recently there are
some BASICs - e.g. OMIKRON BASIC - which give preference to
integers. If you start up the latter BASIC, it will treat all
variables as integers (32 bit) as a default. The makers of this
undoubtely marvellous BASIC explain their choice as an example
of programmer's idealism. As reasons they mention the following:
in most cases one doesn't need floating-point, integer arithmetic
is substantially faster than floating-point (8-10 times !!!). The
Game Creator Basic STOS starts up in integers too. And what about
programming in 68000-Assembler ? You will have to write your
floating-point routines yourself..... I hope, I could convince
you of two important things. First, a language which doesn't
support floating-point as a default, is not an inferior language
at all, as long as you can define routines and use techniques
which let you achieve your goals. Secondly, try and learn to
swim !!


Now let's start a great job: drawing a circle (or more), using
integer arithmetic exclusively. There are other methods which can
do the job even faster. I choose this one for reasons of
demonstration. This method is open - there are no dirty tricks -
and I can proceed in small steps, building up the routine in an
easy way until the final word. So I might understand it too !!
Before you can draw a circle, you should be able to draw. So
we'll have to import and compile a file which contains all
drawing-routines we will need and even more with the command
implements the Line-A-routines, being the fastest drawing-
routines on a ST. Then I initialise the Line-A routines with
{GRAPHICS}. The next thing you should remember is the table
called {SINUS}. I mentioned this table earlier, when we learned
about arrays. This table contains all sinus-values for angles
between 0 and 90 degrees. In order to avoid floating-point
numbers I multiplied each number with 10000. The table contains
90 values, one for each degree. Before I will speak about the
next two words, I'll have to explain something else. We are going
to draw a circle and we are going to do it on a black-and-white
monitor-screen. That's an important observation. We will have to
draw the circle, using screen coordinates. As you'll certainly
know, it is impossible to draw a circle at a screen. It will look
like a circle, but when you will enlarge the picture, you will
see, that in real it is a polygon with lots of angles. We are
going to use this physical feature of a circle on a
computermonitor. To draw a circle at the screen we'll have to
compute 360 points and for each point we need to know 4 items:
the x-coordinate and the y-coordinate of the centre, the radius
and the angle. The x- and y-coordinates of each point on the
circumference are measured from a given point at the screen, the
centre of the circle, by the words {COSINUS} and {SNS}.
Therefore the circle to be drawn is divided into 4 quarter
segments. Now you may read the comments in the program and try to
figure out, how it all works. If you can get a good notion of
what is going on in this little program, I can assure you, that
you then know and understand a lot of FORTH and a lot of your
computer too !!


\ This is a complete sinus-tabel

CREATE SINUS 0 , 175 , 349 , 523 , 698 , 872 , 1045 , 1219 ,
1392 , 1564 , 1736 , 1908 , 2079 , 2250 , 2419 , 2588 ,
2756 , 2924 , 3090 , 3256 , 3420 , 3584 , 3746 , 3907 ,
4067 , 4226 , 4384 , 4540 , 4695 , 4848 , 5000 , 5150 ,
5299 , 5446 , 5592 , 5736 , 5878 , 6018 , 6157 , 6293 ,
6428 , 6561 , 6691 , 6820 , 6947 , 7071 , 7193 , 7314 ,
7431 , 7547 , 7660 , 7771 , 7880 , 7986 , 8090 , 8192 ,
8290 , 8387 , 8480 , 8572 , 8660 , 8746 , 8829 , 8910 ,
8988 , 9063 , 9135 , 9205 , 9272 , 9336 , 9397 , 9455 ,
9511 , 9563 , 9613 , 9659 , 9703 , 9744 , 9781 , 9816 ,
9848 , 9877 , 9903 , 9925 , 9945 , 9962 , 9976 , 9986 ,
9994 , 9998 , 10000 ,

: SIN 4 * SINUS + @ 10000 */ ; ( xcoor radius angle --- n )
: COS 4 * 360 SWAP - SINUS + @ 10000 */ ;
( ycoor radius angle --- n )

VARIABLE X1 VARIABLE Y1 \ to store coordinates

: XYPLOT Y1 ! X1 ! ; \ a little help-word for {PLOT}
: PLOT 2DUP X1 @ Y1 @ DRAW XYPLOT ; \ the drawing-routine

CREATE XAR 364 ALLOT \ 4 arrays to store the coordinates of the
CREATE YAR 364 ALLOT \ actual circle to draw. Each array
CREATE XAR1 364 ALLOT \ contains the coordinates of a quarter
CREATE YAR1 364 ALLOT \ segment of the circle.

\ The following words produce the exact coordinates and store
\ these into the four arrays.

: COSINUS ( ycoor radius --- )
91 0 DO 2DUP I COS - YAR I 4 * + ! LOOP
91 0 DO 2DUP I COS + YAR1 I 4 * + ! LOOP 2DROP ;

: SNS ( xcoor radius --- )
91 0 DO 2DUP I SIN - XAR I 4 * + ! LOOP
91 0 DO 2DUP I SIN + XAR1 I 4 * + ! LOOP 2DROP ;

: COSSIN SWAP OVER COSINUS SNS ( xcoor ycoor radius --- ) ;

: YXPLOT YAR @ XAR @ X1 ! Y1 ! ; \ Four help-words to
: YXPLOT1 YAR @ XAR1 @ X1 ! Y1 ! ; \ calculate the starting-
: YXPLOT2 YAR1 @ XAR1 @ X1 ! Y1 ! ; \ point of each quarter-
: YXPLOT3 YAR1 @ XAR @ X1 ! Y1 ! ; \ segment.

\ Each of the next four words actually plot - point by point - a
\ quarter of a circle.

: 1QUART YXPLOT 91 0 DO XAR I 4 * + @ YAR I 4 * + @ PLOT LOOP ;
: 2QUART YXPLOT1 91 0 DO XAR1 I 4 * + @ YAR I 4 * + @ PLOT LOOP ;
: 3QUART YXPLOT2 91 0 DO XAR1 I 4 * + @ YAR1 I 4 * + @ PLOT LOOP ;
: 4QUART YXPLOT3 91 0 DO XAR I 4 * + @ YAR1 I 4 * + @ PLOT LOOP ;

: CIRCLE ( xcoor ycoor radius --- )

." Draw a circle: xcoordinate ycoordinate radius CIRCLE ." CR
." Example: 200 300 80 CIRCLE . "

The {INFO}-word may be substituted by

.( Draw a circle: xcoordinate ycoordinate radius CIRCLE ) CR
.( Example: 200 300 80 CIRCLE.)

You can leave out now the second {INFO} - which runs the first
one in the original source. With {.( } and { )} we can type
messages at the monitor-screen which will be retyped immediately
back at the screen again, after having pressed [RETURN]. Thus the
word {.(} is not much practical in the interactive mode, as
normally it doesn't make any sense sending messages to yourself.
But for giving a short message to the user on how to use an
application, it is just perfect.


I think, that I've done a great job, promoting integer
arithmetic. Of course I can stand floating-point. Why not ?
Sometimes it is inevitable. But most times you won't need it.
Rather, I know some fellow-FORTH-fanatic, who spent a lot of time
programming floating-point-routines in FORTH. He was a very
enthousiastic programmer, till the moment he - at last - finished
the job. He delivered me his routines to do some error-checking.
I was very curious, if he would ever ask me for the results. When
he will be reading these lines - and you will, David, won't you ?
- he will remember his floating-point master-piece. Would you
like to recieve the results after eight months ? Or don't you
care for them any more ? Well, your routines are impeccable. You
really did a fine job. But I like to do it my way, anyhow.

How, ugh !!


I would like to draw your attention to a new - almost new -
FORTH. It is called FORTHMACS and available through Public
Domain. Three years ago I was given a FORTH-system, called FORTH-
83 distributed by the San Leandro Computer Club (USA). It is this
FORTH I've always liked most. This FORTHMACS vs 1.1 claims to be
the official release of that FORTH. The author is Mitch Bradley.
He is the owner of Bradley Forthware. FORTHMACS can be copied
freely as long as the whole of it is copied and no changes are
made. Public Domain libraries are allowed to charge the normal
fee. The author claims that FORTHMACS is bugfree. Comparing
FORTHMACS with the FORTH-83, it must be said that the first one
is quite an improvement. Here we have a FORTH almost F-83-
Standard. Two exceptions: the stacks are 32-bit and the file-
system for mass-storage is not block-oriented. For editing the
disk contained an improved EMACS-editor. When this editor is
loaded into memory with the word EDIT, it stays resident. Typing
EDIT or ED will bring you back into the editor... and the file. A
manual and a reference-doc is included. For those who prefer
block-editing a file available to install a block-oriented
editor. For quick reference to a word there are two words: SEE,
to look at the definition and WHATIS to look at the function.
The early releases of FORTHMACS are also called UNIX_FORTH. The
latter has been used by me and many others for several years.
Dutch readers should contact BBS ST-HAARLEM for a lot of info.
(Phone 023-340077). Much more information on FORTHMACS is held
on the FORTHMACS-disk.


1. Yes, that must have been rather difficult question. Now here
are two possible solutions. a) Define a word THOUSAND like


or b) Insert a {DROP} after {THEN} in the definition of
2. This answer should have been much easier to find: left of
the pivot-value of course.

3. The value of {I'} must have been one more, so 140.

4. The two new initial values were 0 and 139. So the new pivot
would have been the value stored in 0 139 {+} {2/} = 69 !

5. It is the parameterfield.

6. Here is the definition.



1. Rewrite the calculation we used to get the exact number of
balls (33012 1349 {+} 1350 {/} {.}), so, that we can calculate
the number of balls for any cloth. Like this: 23456 1200
{BALLS}. 23456 is the area of the whole table-cloth, 1200 what
can be made of one ball.
2. In all day life, we truncate quotients like 19.37 to 19 sharp
and round up numbers like 19.67 to 20. Now write a word like
{BALLS} that will do this job: numbers ending larger than
0.49 are rounded up, otherwise they are truncated.
3. The volume of a cone is given by this formula:(?r^2h)/3 or
more readable: (pi * r * r * h) / 3. Define CONE, which will
calculate the volume of a cone. And be smart !!
4. The word {BALLS} you have to define in exercise one, is ment
to round up for a rectangular tablecloth. Could you define one
that would do the same for the circular one ?

The text of the articles is identical to the originals like they appeared in old ST NEWS issues. Please take into consideration that the author(s) was (were) a lot younger and less responsible back then. So bad jokes, bad English, youthful arrogance, insults, bravura, over-crediting and tastelessness should be taken with at least a grain of salt. Any contact and/or payment information, as well as deadlines/release dates of any kind should be regarded as outdated. Due to the fact that these pages are not actually contained in an Atari executable here, references to scroll texts, featured demo screens and hidden articles may also be irrelevant.