4. KEYBOARD INPUT
In his continuing series, Ian Finlayson provides some routines
to handle keyboard input in your program and explains how they work
In this issue I am going to deal with one of the
most common requirements in programming a home computer, that is
keyboard input. There are several ways of obtaining an input to a
program when required and it is worth giving this aspect of your
programs a bit of attention as it can give them a professional feel
if it is handled well, or give a rather poor impression if done
badly.
WHY NOT USE INPUT?
The most straightforward way of getting an input
from the keyboard is through the INPUT command, using "INPUT X" for
a number or "INPUT A$ for a string. There are, however, two reasons
why INPUT is not my chosen way to obtain a keyboard input. First,
for single keystroke entry such as Y/N or single numbers the
response is much slicker if there is no need to wait for the RETURN
key to be pressed. Then there is also the problem of error trapping
which is not easy with INPUT especially when handling strings as the
trap works on the whole string after RETURN is pressed and not on
the individual keystrokes of the string entry. For these reasons I
prefer to use GET instead of INPUT.
DEFENSIVE PROGRAMMING
Before looking at the subroutines themselves let
me mention a programming style called 'defensive programming'. In
commercial programming where a team may be working on one program
this programming technique is essential – each programmer works on
his own modules of the program trying to ensure that there is no way
that other modules being worked on by other members of the team can
conflict with his when they are all combined. This requires a very
analytical, protective point of view, and frequently causes the
program to be quite complex when simple code appears to fulfill the
requirement. Defensive programming is a good technique to adopt in
your own programs if you wish to share them widely. In this case you
are not protecting against conflict with another part of the program
but against mishandling by the user of your program. It is not easy
to make your program totally crash proof but it is a good aim. What
would happen to your masterpiece if a determined youngster tried to
input `INVERSE CONTROL T' when the program was expecting `YES' or
'NO'?
Now to an analysis of the subroutines-
YES or NO INPUT SUBROUTINE
|
|
|
Line 31300 – The first statement disables
the break key to prevent inadvertent interruption of the program.
The way to do this is to ensure that bit 7 at memory location 16 is
not set (this means the value in memory location 16 must be less
than 128). You may use this during initialisation of your main
program, if so it is not needed here in the subroutine but it must
be reset after a Graphics call.
POKEing 694 with 0 ensures the keyboard is not in inverse and
POKEing 702 with 64 makes sure that normal upper case keyboard input
is selected.
Line 31310 – Opens I/O channel 2 for input
from the keyboard, clears the screen and prompts "Play again?
(Y/N)". The program waits for a key press and when this happens
returns the key value (in ATASCII) in the variable TT8 then closes
the I/O channel. If TT8 equals 89 'Y' has been pressed and the RUN
command restarts the program. Instead of the RUN command we could
RETURN to the main program and then GOTO an early line in the
program to play again.
Line 31320 – If 'Y' is not pressed we exit
the program with a "Goodbye". I have assumed that you are using a
disk with a program called MENU on it for selecting your games. You
could alternatively just use an END statement to return to Basic.
SINGLE NUMBER INPUT SUBROUTINE
|
|
|
I have not repeated line 31300 here but it is
equally applicable for crash proofing this subroutine.
Line 31330 – This line is very similar to
31310 and returns the ATASCII value of the key pressed in TT9. The
value of TT9 is then reduced by 48 (The ASCII value of a number is
48 more than its face value). A check is then made to ensure that
the value is between 0 and 9.
Line 31340 – The value selected is printed
on the screen and we return to the main program with the selected
value stored in TT9.
STRING INPUT SUBROUTINE
|
|
|
String input is slightly more complex than the
previous examples as we have a series of characters to deal with.
Line 31350 – Opens the keyboard for input,
prints a prompt, then starts a FOR NEXT loop for the number of
characters you require in the string. I have allowed 20 characters
but you can adjust this to suit your requirements.
Line 31360 – The POKE to 702 is here in
case the inverse key is inadvertently hit between characters. Next
one character is read into TT11 and if its value is 155 (RETURN) it
is assumed that the string is complete so the stack is popped and we
exit the loop to line 31390.
Line 31370 – This line checks for valid
characters. I have allowed A to Z (65-90), a to z (97-122) also
SPACE (32) and DELETE BACKSPACE (126). Allowing backspace means that
a very limited form of correction can be carried out during input,
but each backspace uses up a character from the string so any
extensive correction will cause a problem! Any invalid character is
ignored and causes a loop back to 31360.
Line 31380 – Valid characters are printed
to the screen and also added to the end of the string TT8$. This
string must have been dimensioned in the setting-up sequence of the
main program and must be (at least) the same size as the FOR NEXT
loop in line 31350
Line 31390 – Closes the I/O channel and
returns to the main program.
OTHER APPLICATIONS
This method for keyboard input can be tailored to
your specific requirements. For example, if you want a number input
of more than one digit use the string input subroutine and then
change the string back to a number by using VAL(TT8$).
If you are having trouble with any of these
subroutines write with a s.a.e. and I will try to assist. Ian
Finlayson, 60, Roundstone Crescent, East Preston, West Sussex