In the Letters page of issue 30 of PAGE 6, a method
of getting rid of the question mark prompt when using the INPUT
statement in Atari BASIC was given. The example was:
10 DIM A$(10)
20 ? "ENTER SOMETHING ";:INPUT #16,A$
30 ? A$
Although this solution works, the Editor stated
"don't ask me why!". Well, I believe that I have traced down the
cause of this undocumented feature (or is it a bug?) in good old
Atari BASIC. So, if you bear with me, I will explain the some of the
inner workings of the Atari.
OPEN CHANNEL ZERO
First of all, let us take a look at the format of the
INPUT statement. The command may appear as, e.g. INPUT NAME$, or
INPUT #2,RECORD$. The #2 (or #16) is a channel number identifying
the device from which the input is to be taken. Where the channel
number is absent, #0 is assumed which is the screen editor. The
channel number points to one of the Atari's eight Input/Output
Control Blocks (IOCBs). At this point, you may say if there are only
eight channels or IOCBs, which channel does an INPUT #16 statement
use? From the fact that the example quoted at the top of this
article works, it appears that channel 16 is treated as channel 0.
A BASIC ERROR?
At this point I thought that all that was happening
was that any channel number greater than 7 (the eight IOCBs are
numbered 0 to 7) was being treated as 0. I then tried the example
with INPUT #10 in place of INPUT #16. The result was Error 20, which
when looked up in the back of Your Atari Computer is explained as
"Bad Channel Number — The program tried to use channel 0 or a
channel number larger than 7". Confusion reigned — 10 is larger than
7 and fails, but 16 works! Some further experimentation showed that
channel number 32 works, but using channel 17, error 131 appears ("A
GET or INPUT statement used a channel opened for output only").
AN INSIGHT TO THE PROBLEM
At this point, I started looking through my
collection of Atari-related books and magazine articles. The obvious
place to find the key to this obscure mystery seemed to be one of
Bill Wilkinson's 'Insight: Atari' articles in COMPUTE! magazine.
After some delving I found the clue I needed in Bill's articles in
the November 1981 and January 1985 issues. Both columns describe the
use of IOCBs, particularly as used from assembly language. Bill
explained that when undertaking input/output in assembly language
via CIO, the program should specify which channel to use by passing
the relevant IOCB number times 16 in the X-register. Each IOCB is 16
bytes long, so the X-register value is used as an offset to the
start of the whole IOCB area.
HOW MUCH CAN YOU PUT IN A BYTE?
Things began to fall in place now. When an INPUT
command specifies channel n, the Atari operating system is actually
using 16 times n. So, channel 0 is 0, but channel 1 is 16, channel 2
is 32 ... channel 10 is 160 ... channel 16 is 256, channel 17 is
272, etc. However, an eight-bit computer like the Atari stores
values in bytes of memory where each byte consists of eight bits —
the maximum value in one byte is 255, thus any value greater than
255 must occupy two bytes. I now turned to COMPUTE! Books' Atari
BASIC Source Book compiled by Bill Wilkinson (who else?) and began
to peruse the listing of the original source code for Atari BASIC
included in that publication.
MULTIPLICATION IS THE NAME OF THE GAME
After studying the source code for a while I managed
to identify what was happening. There are in fact two areas to
consider. Firstly, when processing an INPUT command, BASIC only
prints a '?' prompt if the channel number supplied is 0 (zero). Thus
for channels 1 to 7 (corresponding to the remaining IOCBs), no '?'
is printed when an INPUT command is processed. Secondly, the input
channel number is multiplied by 16 to be passed to the CIO system to
specify the relevant IOCB. Logically, the channel number is not
expected to be greater than 7. Unfortunately, BASIC uses a one-byte
field to pass the channel number times 16 to the CIO system to
initiate an INPUT command. However, this field is validated to see
if it is not greater than 7 times 16 by checking if the field is
negative by using a BMI instruction. In an eight-bit byte, the
setting of the most significant (left-most) bit indicates a negative
value. Take a look at the binary equivalents in Table 1.
In the right hand portion of the Binary equivalent
column, values equivalent to channels 8 to 15 inclusive have their
negative bit set and result in an Error 20 from BASIC. Channel 16
results in a binary equivalent setting the least significant bit in
the left hand portion only, the right hand portion remains
equivalent to zero. Consequently, BASIC can be fooled if a channel
number which is a multiple of 16 is supplied in the INPUT statement
because the byte being tested remains zero.
Channel |
Channel x 16 |
Binary equivalent |
|
|
|
|
0 |
0 |
00000000 |
00000000 |
1 |
16 |
00000000 |
00010000 |
2 |
32 |
00000000 |
00100000 |
3 |
48 |
00000000 |
00110000 |
4 |
64 |
00000000 |
01000000 |
5 |
80 |
00000000 |
01010000 |
6 |
96 |
00000000 |
01100000 |
7 |
112 |
00000000 |
01110000 |
8 |
128 |
00000000 |
10000000 |
... |
... |
... |
... |
15 |
240 |
00000000 |
11110000 |
16 |
256 |
00000001 |
00000000 |
17 |
272 |
00000001 |
00010000 |
... |
... |
... |
... |
32 |
512 |
00000010 |
00000000 |
THE QUESTION
ANSWERED
Referring back to the original example then, because the channel
number specified in the INPUT command is a multiple of 16, it is
acceptable as a valid parameter because it in turn is multiplied by
16 and the least significant byte remains at zero indicating channel
0 (the screen editor). However, because the value in the channel
actually specified in the INPUT command is not zero, the '?' prompt
does not appear.
Hopefully, this convoluted investigation will explain
why there is a way to get rid of the '?' prompt when using the INPUT
command and the screen editor.
My thanks must go to Bill Wilkinson for all the bits
of information and insight (no pun intended) that he has provided to
Atari enthusiasts over the years. Without the background data that
he has published I am sure our understanding of the Atari would not
be as great as it today.
top