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:
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 sample:
OPEN "COM2:2400,N,8,1,RB2048,TB2048" FOR RANDOM AS #1Now, 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 dont 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 transmition 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, dont worry, there is a way around that which involves switching the memory addresses on the COM ports. Dont 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. Dont 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 alot easier than it sounds. All of these commands begin with "AT". Here are the most used ones:
|---------------------------------------------------------------------------| | MODEM LANGUAGE | TRANSLATION TO ENGLISH | |---------------------------------------------------------------------------| | "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.)
CLS PRINT "Openning 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!" DO LOOP UNTIL INKEY$ = CHR$(27) PRINT #1, "ATZ"Now that wasnt 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 transmittion, 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.
CLS 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 "OPTIONS:" PRINT "1-Dial up to another computer" PRINT "2-Wait for a call" PRINT "3-Quit" DO a = VAL(INKEY$) LOOP UNTIL a >= 1 AND a <= 3 IF a = 3 THEN CLOSE : SYSTEM IF a = 2 THEN GOTO wait PRINT "Number to call?" INPUT ">", number$ PRINT #1, "ATDT" + number 'Tell the modem to dail the number. GOTO chat wait: 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$ = "" DO 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. chat: 'If you where waiting for a call, alot of ASCII characters will be printed 'on the screen. Dont worry, that just the computers getting in sync and 'talking. You also will not see what you type. CLS PRINT "You are now ready to chat, press ESC to quit." DO 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 'computer 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 statmentAnd thats 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 aquired 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 alot.
Happy hacking everyone!