[comp.sys.atari.st] Atari GEMVDI programming

steve@bungia.mn.org (Steve Yelvington) (08/21/89)

chrisl@fulcrum.bt.co.uk writes...

> I am about to embark on the writing of a fairly major piece of programming on
> a 1040 ST with Mark Williams C (I think). I am writing a windowing application
> which will also have to gather data from the ST serial port.
> Can anyone recommend
> 	a) a good introductory text on programming, particularly the serial
>   	   interface and the windowing features,
> 	b) a good reference work for the same features

As an introductory text on GEM programming, I would recommend:
    Atari ST Application Programming
    Lawrence J. Pollack 
    Eric J.T. Weber
    Datatech Publications
    Bantam Books
    ISBN 0-553-34397-1
 If the book isn't available in the U.K., try contacting Bantam at 666
Fifth Avenue, New York NY 10103 USA.

The serial interface is another matter entirely. You don't really NEED to
know much about it to make it work -- the logical AUX device actually is a
FIFO buffer maintained by an interrupt-driven communications routine built
into TOS. All you have to do is poll the AUX device using the Cauxis/
Cauxin GEMdos calls or the equivalent Bconstat/Bconin at the BIOS level.
You don't have to install your own interrupt service routines or other
MS-DOS-like brain-damage-control measures.

A couple of tricks:

Rsconf(baud,flow,uc,rs,ts,sc) WORD baud, flow, uc, rs, ts, sc
configures the RS232C port. Some legal "baud" values are:
	0 == 19.2 kb 
	1 == 9600
	2 == 4800
  	4 == 2400
	7 == 1200
	9 == 300
Values for flow are:
        0 == no flow control (default)
        1 == xon/xoff
        2 == RTS/CTS  (whether it works is another matter entirely)
        3 == both xon/xoff and RTS/CTS
The rest of the parameters are best left untouched unless you really want
to get bizarre. To avoid changing the value of a setting, use -1. For
example. Rsconf(7, -1, -1, -1, -1, -1) will set the speed to 1200 and
leave the other settings unchanged.

Another useful call:

Iorec(iodev) WORD iodev
returns a pointer to an input buffer descriptor structure, which is
immediately followed by the output buffer descriptor in the same format.
By poking around in these structures, you can repoint the queue to your
own buffer of a larger or smaller size. 

Why would you want to do this? Suppose you're receiving Ymodem. As soon as
you get a packet, you ACK it, THEN you start writing to disk. Since you
wisely have made the input buffer > 1K, the interrupt-driven i/o routine
has a place to stuff ALL of the next incoming block, even if you have very
slow disk drives and a very fast modem.

(I once made the mistake of trying Tom Zerucha's WXmodem (windowing xmodem)
program without using his companion TSR utility to expand the input buffer
... and I was writing to a floppy disk. It was a disaster!)

Here's what the structure looks like:

   struct iorec {
                char *buffer;        /* pointer to FIFO queue  */
                WORD buf_size,       /* size of the FIFO queue */
                     buf_head,       /* queue head index       */
                     buf_tail,       /* queue tail index       */
                     buf_low,        /* when to turn flow ON   */
                     buf_hi;         /* when to turn flow OFF  */
                }

If you fool around with this stuff, don't forget to restore the pointers
and values before your program terminates, or the next program may get a
very rude shock from the AUX port!

Hope this helps.

This message is in the public domain.

  -- Steve Yelvington, up at the lake in Minnesota
  ... bungia.mn.org!stag!thelake!steve