From: Richard B. Gilbert [76702.1567@compuserve.com]
Sent: Friday, September 03, 1999 12:33 AM
To: Info-VAX@Mvb.Saic.Com
Subject: Setting RTS/CTS signals

Message text written by INTERNET:maltenbe@debis.com
>I want to develop a driver for the serial-line on a VAX (VMS5.5-2) in
the programming language "C". How can I set the RTS/CTS signals for the
hardwarehandshake? I'm working with 1200 bit/sec and halfduplex.
<

        Well, you *can't* set CTS!

        Here's an example program that may illustrate how to turn on, or
off, the signals that you can turn on and off.

/*
  Copyright 1995
  Richard B. Gilbert
  All rights reserved.
  <76702.1567@CompuServe.Com>

        This program is intended to be used with a breakout box to
determine
  the signals that are supported by a serial port.  The program translates
the
  logical name TEST_DEVICE to determine name of the serial port you want to
  test.

        First it determines what sort of controller you are dealing with. 
It
  recognizes and reports: DZ11,  DZ32, DMF32, DMB32, DMZ32, DHV-11, DHU-11,
  and LAT; otherwise it reports "Unknown".  OPAn: ports will  most likely
  be reported as Unknown.

        It sets DTR, RTS and Secondary Tx.  It then reports the signals it
  sees from the set: DSR, RING, Carrier Detect, CTS and SECREC.  Use a
  breakout box to force these signals true in order to determine which of
them
  can actually be detected.  After a one second pause, it turns of DTR, RTS
  secondary Tx, then senses and reports the input signals again.

        If you don't have a breakout box, you can use a loopback connector
  that connects DTR to DSR, CD, and RING; RTS to CTS; and SecTX to SecRec.

 */
#if defined __DECC
#pragma message disable dollarid
#endif
#include        <stdio.h>
#include        <stdlib.h>
#include        <descrip.h>
#include        <signal.h>
#include        <starlet.h>
#include        <iodef.h>
#include        <ttdef.h>
#include        <dcdef.h>
#include        <lib$routines.h>

int main(int argc, char **argv);
void list_modem_signals(char);

int main(int argc, char **argv)
{
        struct {
                unsigned short  cond_val;
                unsigned short  count;
                unsigned long   device_specific;
                } iosb;
        struct {
                char    reserved_1;
                char    reserved_2;
                char    modem_on;
                char    modem_off;
                char    filler[4];
                } set_mode_p1;
        struct {
                char    controller_type;
                char    reserved_3;
                char    receive_modem;
                char    filler_2[9];
                } sense_mode_p1;
        struct set_mode_buffer
               {
                char    class;
                char    type;
                short   buffer_size;
                long    basic_chars;
                long    extended_char;
                };
        struct set_mode_buffer mode_buffer, nomodem_mode;

        static  $DESCRIPTOR(port_desc, "TEST_DEVICE");
        unsigned long ret_status, io_func;
        unsigned short chan;

        printf(" Copyright 1995.\n Richard B. Gilbert\n All rights
reserved.\n");
        ret_status = sys$assign(&port_desc, &chan, 0, 0, 0);
/*
   Save the port characteristics for later.
 */
        ret_status = sys$qiow(0, chan, IO$_SENSEMODE, &iosb, 0, 0,
                &mode_buffer, sizeof(mode_buffer), 0, 0, 0, 0);
/*
   Learn what sort of controller we are dealing with.
 */
        io_func = IO$_SENSEMODE | IO$M_RD_MODEM;
        ret_status = sys$qiow(0, chan, io_func, &iosb, 0, 0,
                &sense_mode_p1, sizeof(sense_mode_p1), 0, 0, 0, 0);
        if ((ret_status & 7) != 1) lib$stop(ret_status);
        if ((iosb.cond_val & 7) !=1) lib$signal(iosb.cond_val);
        printf("\n Controller type is ");
        switch (sense_mode_p1.controller_type)
                {
                case DT$_DZ11:  printf("DZ11\n");
                                break;
                case DT$_DZ32:  printf("DZ32\n");
                                break;
                case DT$_DMF32: printf("DMF32\n");
                                break;
                case DT$_DMB32: printf("DMB32\n");
                                break;
                case DT$_DMZ32: printf("DMZ32\n");
                                break;
                case DT$_DHV:   printf("DHV-11\n");
                                break;
                case DT$_DHU:   printf("DHU-11\n");
                                break;
                case DT$_LAT:   printf("LAT\n");
                                break;
                default:        printf("Unknown (%d)\n",
                                        sense_mode_p1.controller_type);
                }
        list_modem_signals(sense_mode_p1.receive_modem);
/*
   Set the port /NOMODEM.
 */
        nomodem_mode = mode_buffer;
        nomodem_mode.basic_chars = mode_buffer.basic_chars & (!TT$M_MODEM);
        ret_status = sys$qiow(0, chan, IO$_SETMODE, &iosb, 0, 0,
                &nomodem_mode, sizeof(nomodem_mode), 0, 0, 0, 0);
/*
   Turn on RTS, DTR and Secondary TX.
 */
        printf(" Turning on RTS, DTR and Secondary Tx\n");
        set_mode_p1.modem_on = TT$M_DS_RTS | TT$M_DS_DTR | TT$M_DS_SECTX;
        ret_status = sys$qiow(0, chan, IO$_SETMODE | IO$M_SET_MODEM |
IO$M_MAINT,
                &iosb, 0, 0, &set_mode_p1, 0, 0, 0, 0, 0);
        if ((ret_status & 7) != 1) lib$stop(ret_status);
        if ((iosb.cond_val & 7) !=1) lib$signal(iosb.cond_val);
#pragma nostandard
        sleep(1);
#pragma standard
        ret_status = sys$qiow(0, chan, IO$_SENSEMODE | IO$M_RD_MODEM,
                &iosb, 0, 0, &sense_mode_p1, 0, 0, 0, 0, 0);
        if ((ret_status & 7) != 1) lib$stop(ret_status);
        if ((iosb.cond_val & 7) != 1) lib$signal(iosb.cond_val);
        list_modem_signals(sense_mode_p1.receive_modem);
        sleep(5);
/*
   Turn off RTS, DTR, and Secondary TX.
 */
        printf(" Turning off RTS, DTR and Secondary Tx\n");
        set_mode_p1.modem_on = 0;
        set_mode_p1.modem_off = TT$M_DS_RTS | TT$M_DS_DTR | TT$M_DS_SECTX;
        ret_status = sys$qiow(0, chan, IO$_SETMODE | IO$M_SET_MODEM |
IO$M_MAINT,
                &iosb, 0, 0, &set_mode_p1, 0, 0, 0, 0, 0);
        if ((ret_status & 7) != 1) lib$stop(ret_status);
        if ((iosb.cond_val & 7) != 1) lib$signal(iosb.cond_val);
        sleep(1);
        sense_mode_p1.receive_modem = 0;
        ret_status = sys$qiow(0, chan, IO$_SENSEMODE | IO$M_RD_MODEM,
                &iosb, 0, 0, &sense_mode_p1, 0, 0, 0, 0, 0);
        if ((ret_status & 7) != 1) lib$stop(ret_status);
        if ((iosb.cond_val & 7) != 1) lib$signal(iosb.cond_val);
        list_modem_signals(sense_mode_p1.receive_modem);
/*
   Restore the port to the way we found it.
 */
        ret_status = sys$qiow(0, chan, IO$_SETMODE, &iosb, 0, 0,
                &mode_buffer, 0, 0, 0, 0, 0);
        exit(1);
}
void list_modem_signals(char receive_modem)
{
        printf("\n");
        if ((receive_modem & TT$M_DS_DSR) != 0) printf("DSR ");
        if ((receive_modem & TT$M_DS_RING) != 0)        printf("RING ");
        if ((receive_modem & TT$M_DS_CARRIER) != 0)     printf("CARRIER ");
        if ((receive_modem & TT$M_DS_CTS) != 0) printf("CTS ");
        if ((receive_modem & TT$M_DS_SECREC) != 0)      printf("SECREC ");
        printf("\n");
}