[comp.sys.ibm.pc.misc] Reading modem registers in C.

rmorris@hubcap.clemson.edu (Robert Morris) (08/15/90)

I'm trying to read the registers in a Hayes 2400 modem.  I issue a 
ATS#? (# - number of the register).  I then check 0x3f8 for the value.
What I get is an unlikely result (ie. 13 - number of rings that occurred 
and no one called).  I figure the 13 is the carriage return sent to the modem.
I'm using Turbo C 2.01 and would appreciate any help recieved.
						Thanks,
						Robert Morris
						RMORRIS@hubcap.clemson.edu

roy@cs.umn.edu (Roy M. Silvernail) (08/16/90)

rmorris@hubcap.clemson.edu (Robert Morris) writes:

> I'm trying to read the registers in a Hayes 2400 modem.  I issue a 
> ATS#? (# - number of the register).  I then check 0x3f8 for the value.
> What I get is an unlikely result (ie. 13 - number of rings that occurred 
> and no one called).  I figure the 13 is the carriage return sent to the modem
> I'm using Turbo C 2.01 and would appreciate any help recieved.

I figure you're right. Your modem is most likely sending an ASCII string
representing the status of the register, and 0x3f8 will only contain the
latest character received from the modem.

If you're using a Fossil driver, the problem is easily solved by reading
characters waiting in the input buffer (using INT 14h). If not, you'll
have to incorporate some kind of input buffering (in effect, a
mini-comm program), and read the waiting characters from the buffer.

Hope this helps.

--
    Roy M. Silvernail   | #include <stdio.h>                 | Does virtual
    now available at:   | main(){                            | reality need
 cybrspc!roy@cs.umn.edu |  float x=1;                        | swap space?
(cyberspace... be here!)|  printf("Just my $%.2f.\n",x/50);} | -- me

dgil@pa.reuter.COM (Dave Gillett) (08/16/90)

In <10133@hubcap.clemson.edu> rmorris@hubcap.clemson.edu (Robert Morris) writes:
>I'm trying to read the registers in a Hayes 2400 modem.  I issue a 
>ATS#? (# - number of the register).  I then check 0x3f8 for the value.
>What I get is an unlikely result (ie. 13 - number of rings that occurred 
>and no one called).  I figure the 13 is the carriage return sent to the modem.
>I'm using Turbo C 2.01 and would appreciate any help recieved.

The first character of the response won't be available in the Receive Buffer
Register until Data Ready (bit 0 of the Line Status Register) is turned on.
Then you have to grab that character before the next one arrives.  Yeuchh!

This is basically what the BIOS INT 14H service does.  Except that if you use
INT 14H, there's some chance of your code working with communications setups
that aren't quite asynch ports (such as across a LAN to an asynch server).

If you decide that polling the UART is no fun, you can turn on Data available
(bit 0 in the Interrupt Enable Register) and Out2 in the Modem Control register,(and you may have to toggle bit 4 in the Interrupt Mask Register--which is in
the 8259, not the UART, so it's at a completely different address), and the
system will generate an INT 0CH each time there's a character ready.  Of course,
before you turn those bits on, you set the vector for INT 0CH to point at an
interrupt function that reads the Receive Buffer Register and puts the
character in a buffer that you can read from elsewhere in your program.
(Save the old vector so you can restore it, so line noise doesn't cause an
attempt to call your routine after it's not in memory any more; turn off the
various bits as part of the restore, too.)

Of course, your compiler library probably provides a variety of file I/O
routines which should work on the AUX: device, so if all you're doing is
alternately sending and receiviing strings (especially if you don't really
care how fast the characters are coming) those are probably sufficient.

Plug:  Gofton, Peter W., _Mastering Serial Communications_, Sybex, 1986.
       Don't write PC asynch code without it--or something at least as good.

                                                        Dave