Matthew River Knight of HORIZONS Interactive Entertainment

The modem has probably been the most influential computing device that has yet
been created. Its creation has resulted in a complete change in the world
of business and advertising, has resulted in cheaper and more efficient
international communication, and last, but certainly not least, has had a huge
impact on both the computer professional and the hobbyist. To most, the modem
is a little magic box that opens our computer to the world. In reality, it is
very simple to use, and more importantly, to program. The modem takes bytes of
data, turns it into a noise, and sends it over the phone line. Theoretically,
if you could whistle fast enough and at the right pitches, you could send a
file with the sounds you make. Basically, the computer sends a file over the
modem like this: the modem sends an ASCII character to tell the other computer
it is sending a file. It then breaks up that file into chunks and sends it in
chunks of bytes. The modem then waits for an ASCII character from the other
computer telling it that all is well, and to send the next chunk.

That is all very interesting, you say, but how do I do it in Qbasic? Well,
that is very simple. There are just 4 commands you are going to need to do
some modem communications! They are as follows:

Let's say you want to read all the data from "text.txt", you will do this
OPEN COM Open up the modem for use by Qbasic
INPUT$ Get data from the modem.
LOC Tells you if the modem has any data from an outside source.
PRINT # Send data to the modem.

To start work with the modem, you have to open a "path" to it. This is just
like opening a file, except you use the "OPEN COM" statement. Here is a

OPEN "COM2:2400,N,8,1,RB2048,TB2048" FOR RANDOM AS #1

Now, you wonder what that all means, but it really is quite simple, you just
must remember this little secret: opened devices (like the modem) act just
like opened files! Now back to the example code above. I know it looks
confusing at first, but don't worry, the only thing you need to concern your-
self with is the number between "COM" and ":" and the number between ":" and
",N". All the other stuff deals with transmission settings and the RB TB things
deal with uploading and downloading. The first value is the COM port number
that your modem is on. Because Qbasic was made a long time ago, you only have
access to ports 1 and 2. If your modem is on another port, don't worry, there
is a way around that which involves switching the memory addresses on the COM
ports. Don't worry about that now though, I'll go into that in another article
some time.

The 2nd number is the Baud. BAUD is the speed of the modem. Qbasic cant access
COM ports at any higher speed than 9600, so if you have a 56K modem, Qbasic
can still use it, but it wont go any faster than 9600. Don't worry about this
too much though, I am busy writing a library that gives you access to the
modem at any speed.

To send data to your modem you use the PRINT #n statement, where n is the
file number (in the example, 1.) But there is no point sending stuff like
"Hello world" to your modem right now, because you are not connected to
anything. All you have done with the "OPEN COM" statement, is made a path
from your modem to your program so they can talk to each other.

Hmmm, this is quite a problem. So how do we get connected to something then?
Well, when you want your modem to talk to an outside source, like a BBS, you
have to tell the modem to dial a number. To do this you must know that all
modems have a set of commands eched in their read-only-memory chips that allow
them to do different things. You cant just say "Hey modem, dial 555-314-545",
you gotta talk in the modems lingo! This is a lot easier than it sounds. All
of these commands begin with "AT". Here are the most used ones:

Let's say you want to read all the data from "text.txt", you will do this
ATDT###-###-#### Hey modem, dial ###-###-####
ATZ Hang up the phone!
ATS0=# Wait until you someone calls and the phone rings # number of times, then try to connect modems.
ATM2H1L# Set your speaker volume at # (1-3)

So, if you wanted to call someone with the modem, you would first use an
OPEN COM statement, to get the path between your modem and your prog set up,
then you would use an INPUT statement to get the phone number to dial as a
string, then use PRINT #n to talk to the modem. I think now is a pretty
good time for an example! Here is a simple phone dialer:

(Replace COM# with the COM port your modem is on.)

PRINT "Opening a path to your modem..."
OPEN "COM2:2400,N,8,1,RB7048,TB7048" FOR RANDOM AS #1
PRINT "Please enter the phone number you wish to call"
INPUT PhoneNumber$
PRINT "Talking to your modem..."
PRINT #1, "ATDT"; PhoneNumber$
PRINT "There you go, pick up the phone and talk!"
PRINT "Press the ESC key to hang up!"

Now that wasn't so hard was it? But here comes the biggest problem of modem
control in Qbasic, HOW DO I READ WHAT COMES FROM THE MODEM? Well there is a
little function called LOC that does this. The syntax is:

LOC(n) where n is the file number, which if you used my sample, would be 1.

LOC tells you where in a file you are. File? But I am trying to access the
modem! As I said before, files and devices work the same way. But with a
modem, LOC tells if it has received anything. Fine, now you know if the modem
is getting stuff, but how do you know what it is getting? For that you use the
INPUT$(x,y) statement. x is the number of bytes to get from a file/device and
y is the number of the opened file/device.

x should ALWAYS be 1. I know this means that only 1 character can be read on
each pass, but this way EVERY character is read, and none are skipped. If you
were getting an 11 byte transmission, and x was 2, only the first 10
characters would be read (because it is a multiple of 2.) The last part would
be skipped. This is the way for NORMAL communications. Keep x as 1!

There is just one more modem command to talk about, namely, the "ATSO=#"
command, which you use to wait for a call. But I think it is best explained
with an example. Oh, what the heck, lets just put everything we have learned
here together into a fully commented communications program. You can use this
to call up any BBS and interact with it. Note that it has no uploading or
downloading capabilities, though. I will have to cover this, along with some
other stuff, in another tutorial some time.

PRINT "HORIZONS Interactive Entertainment - BasHack v1."
PRINT "What COM port does your modem use?"
INPUT ">", port$
baud$ = "9600" '9600 should work fine with most modems. If you have
               'an older one use 2400.
               'Open up that com port.
OPEN "COM" + port$ + ":" + baud$ + ",N,8,1,RB2048,TB2048" FOR RANDOM AS #1

PRINT "1-Dial up to another computer"
PRINT "2-Wait for a call"
PRINT "3-Quit"
LOOP UNTIL a >= 1 AND a <= 3
IF a = 2 THEN GOTO waits

PRINT "Number to call?"
INPUT ">", number$
PRINT #1, "ATDT" + number$ 'Tell the modem to dail the number.
GOTO chat
PRINT #1, "ATS0=1" 'Tell modem to conect after 1 ring.

'When a modem connects it returns "CONNECT ####"
'The next hunk of code waits until the modem connects before moving on

a$ = ""
IF LOC(1) THEN a$ = a$ + INPUT$(1, 1) 'if anything in modem add it to a$
LOOP UNTIL INSTR(a$, "CONNECT") 'Wait until modem have connected.

'If you where waiting for a call, a lot of ASCII characters will be printed
'on the screen. Don't worry, that just the computers getting in sync and
'talking. You also will not see what you type.

PRINT "You are now ready to chat, press ESC to quit."
t$ = INKEY$
IF LEN(t$) THEN PRINT #1, t$    'if you typed something send it to the modem
                                'this will be send by the modem to the other
IF LOC(1) THEN r$ = INPUT$(1, 1)'if the is something to get, get it and save
                                'it as r$
IF LEN(r$) THEN PRINT r$;       'if r$ <> "" then print it. the ";" means a
                                'line is not started
LOOP UNTIL t$ = CHR$(27)        'keep doing this until ESC is pressed
PRINT #1, "ATZ"                 'tell the modem to hang up
CLOSE                           'close the open com statment

And that's it! Simple huh? Now you have a cool program that you can use to
talk with your friends over the modem in Qbasic! Before I leave you to
experiment with your newly acquired knowledge, I would like to extend my
thanks to the following people who have helped me some way along the line
with my programming in general: LordAcidus, Petter Holmberg, Tek, ZKman, and
last but not least, Christian Garms. You guys have helped me a lot.

This article originally appeared in The BASIX Fanzine Issue 17 from April 2000.