home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 203_01 / yam5.c < prev    next >
Text File  |  1979-12-31  |  17KB  |  736 lines

  1. /*
  2. $title ('yam5.c: user specific routines')
  3. $date (21 OCT 85)
  4. */
  5. /*
  6.   basic low-level modem functions
  7. */
  8.  
  9. #include <dos.h>
  10. #include "yam.h"
  11. char portmode;        /* baud, parity, stop bit configuration byte */
  12. unsigned io_config; /* hardware config byte */
  13.  
  14.     /* offsets to status ports */
  15. #define ierport Dport+1
  16. #define iicport Dport+2
  17. #define lcrport Dport+3
  18. #define mcrport Dport+4
  19. #define mcsport Dport+6
  20.  
  21. #define serialio 0x14
  22. #define get_io_config 0x11
  23.  
  24. /* serial equates for int 14h in MS-DOS, IBM-PC, Zenith Z-160 */
  25. #define baudmask 0xe0  /* baud rate mask */
  26. #define B110 0
  27. #define B150 0x20
  28. #define B300 0x40
  29. #define B600 0x60
  30. #define B1200 0x80
  31. #define B2400 0xA0
  32. #define B4800 0xC0
  33. #define B9600 0xE0
  34. #define wlenmask 0x3   /* word length mask */
  35. #define len7 2
  36. #define len8 3
  37. #define parmask 0x18   /* mask for parity bits */
  38. #define nopar  0
  39. #define even   0x18
  40. #define odd    0x8
  41. #define stopmask 0x4   /* mask for stop bits */
  42. #define stop1  0x0
  43. #define stop2  0x4
  44.  
  45. /* modem command equates for 8251 */
  46. #define dtr 0x01
  47. #define rts 0x02
  48.  
  49. #define l6mode (len7 | even | stop2)
  50. #define normode (len8 | stop1 | nopar)
  51.  
  52. /****************************************************************************
  53. FUNCTION:
  54.     send initialzation  sequence to CRT.  Some people like the screen to
  55.     be cleared, etc.
  56.  
  57. CALLING PARAMETERS:
  58.     none.
  59. ===========================================================================*/
  60. terminit()
  61. {
  62. } /* terminit */
  63.  
  64.  
  65. /****************************************************************************
  66. FUNCTION:
  67.     change modem port to alternate modem port.  Only ports 0 and 1 are 
  68.     supported as interrupts must be available for the driver.
  69.  
  70. CALLING PARAMETERS:
  71.     port:
  72.         number of port to change to.  For IBM PC, this is 0 or 1
  73. ===========================================================================*/
  74. chngport(port)
  75. int port;
  76. {
  77.         /* first check to see if port exists.  bits 9-11 of confuration
  78.            says how many ports in system */
  79.     if ( (port > ( (io_config>>9)&0x7)-1) || (port > 1) )
  80.     {
  81.         printf("port not availablet\n");
  82.         return ERROR;
  83.     }
  84.     else
  85.     {
  86.             /* disable current port */
  87.         dsblcm();
  88.         resport(commport);
  89.  
  90.             /* set new port */
  91.         switch(port)
  92.         {
  93.             case 1:
  94.                 Dport = 0x2f8;
  95.                 commport = 1;
  96.                 break;
  97.             default:
  98.                 Dport = 0x3f8;
  99.                 commport = 0;
  100.         }
  101.     }
  102.         /* enable new port */
  103.     setport(commport);
  104.     enblcm(0);
  105.     return OK;
  106. } /* chngport */
  107.  
  108.  
  109. /****************************************************************************
  110. FUNCTION:
  111.     peform special user init routines.  Called from INIT() at load time
  112.     with resetflag false.  Called from RESET with resetflag true.  If reset
  113.     flag is true, the port will be reset to the last value as defined by set
  114.     baud, or initialization.  This allows the port to be reset and the current
  115.     state of the port displayed.  Some systems allow configuration of the
  116.     serial port to be read.   IBM does not, so to retain IBM compatiblity
  117.     that data is assumed unavailable.
  118.  
  119. CALLING PARAMETERS:
  120.     resetflag:
  121.         if true, serial port and modem will be initialzed to default condition.
  122. ===========================================================================*/
  123. userinit(resetflag)
  124. int resetflag;
  125. {
  126.     union REGS inregs;
  127.     union REGS outregs;
  128.  
  129.         /* get i/o configuration byte */
  130.     int86(get_io_config,&inregs,&outregs);
  131.     io_config = outregs.x.ax;
  132.  
  133.         /* reset port mode */
  134.     if (resetflag)
  135.     {
  136.             /* baudrate is already set to a default value */
  137.         setbaud(Baudrate);
  138.  
  139.             /* modem will not accept command unless TR is true(terminal
  140.                ready) */
  141.         offhook();
  142.  
  143.             /* set modem configuration:
  144.                 wait 100 seconds for carrier
  145.                 answer on first ring
  146.                 enable connect 1200 message,
  147.                 echo result codes
  148.             */
  149.         sendstring("ATS7=100 S0=1 X1 Q0\r");
  150.  
  151.             /* slight delay needed after commands */
  152.         sleep(5);
  153.                         
  154.             /* set back on hook so will not answer phone */
  155.         onhook();
  156.     }
  157.  
  158. } /* userinit */
  159.  
  160.  
  161. /****************************************************************************
  162. FUNCTION:
  163.     perform user required clean up before exit
  164.  
  165. CALLING PARAMETERS:
  166.     none.
  167. ===========================================================================*/
  168. userexit()
  169. {
  170.         /* reset comm port interrupt */
  171.     resport(commport);
  172.         /* disable interrupts */
  173.     dsblcm();
  174.         /* reset interrupt vectors */
  175.     res_comm();
  176. }
  177.  
  178.  
  179. /****************************************************************************
  180. FUNCTION:
  181.     set serial port mode.  Baud rate, start, stop and parity are set
  182.     via interrupt 14h.
  183.  
  184. CALLING PARAMETERS:
  185.     mode:
  186.         mode byte as defined in int 14h.
  187. ===========================================================================*/
  188. setmode(mode)
  189. char mode;
  190. {
  191.     union REGS inregs;
  192.     union REGS outregs;
  193.  
  194.         /* dx contains port number */
  195.     inregs.x.dx = commport;
  196.  
  197.         /* this routine always does a set command */
  198.     inregs.h.ah = 0;
  199.  
  200.         /* set mode */
  201.     inregs.h.al = mode;
  202.  
  203.         /* send command thru bios */
  204.     int86(serialio,&inregs,&outregs);
  205.     if (outregs.h.ah & 0x80)
  206.         printf("MODEM PORT TIMEOUT STATUS= %x \007\n",outregs.x.ax);
  207.  
  208. } /* setmode */
  209.  
  210.  
  211. /****************************************************************************
  212. FUNCTION:
  213.     set baud rate for serial port.  This routine uses the monitor setup
  214.     routine, which should be compatible with most IBM PC's.
  215.  
  216. CALLING PARAMETERS:
  217.     baud:
  218.         unsigned integer representing baud rate desired.
  219. ===========================================================================*/
  220. setbaud(baud)
  221. int baud;
  222. {
  223.     unsigned ratediv;
  224.  
  225.     Baudrate = baud;
  226.     switch(baud)
  227.     {
  228.         case 110:
  229.             ratediv = B110;
  230.             break;
  231.         case 150:
  232.             ratediv = B150;
  233.             break;
  234.         case 300:
  235.             ratediv = B300;
  236.             break;
  237.         case 600:
  238.             ratediv = B600;
  239.             break;
  240.         case 1200:
  241.             ratediv = B1200;
  242.             break;
  243.         case 2400:
  244.             ratediv = B2400;
  245.             break;
  246.         case 4800:
  247.             ratediv = B4800;
  248.             break;
  249.         case 9600:
  250.             ratediv = B9600;
  251.             break;
  252.         default:   /* use existing rate */
  253.             Baudrate=readbaud();
  254.             ratediv = portmode & baudmask;
  255.         }
  256.  
  257.         /* set serial port baud rate */
  258.     portmode = ((portmode & ~baudmask) | ratediv);
  259.     setmode(portmode);
  260.  
  261.     display_status();
  262. } /* setbaud */
  263.  
  264.  
  265. /****************************************************************************
  266. FUNCTION:
  267.     print modem status to console.
  268.  
  269. CALLING PARAMETERS:
  270.     none.
  271. ===========================================================================*/
  272. display_status()
  273. {
  274.     char mode;
  275.  
  276.     mode = portmode & 0x1f;
  277.  
  278.     if (mode == l6mode)
  279.         printf("Level 6");
  280.     else if (mode == normode)
  281.         printf("normal");
  282.     else
  283.         printf("special");
  284.     printf(" mode\n");
  285.  
  286.     printf("Baud rate = %d\n",readbaud());
  287. } /* display_status */
  288.  
  289.  
  290. /****************************************************************************
  291. FUNCTION:
  292.     send break to modem if break key is pressed.
  293.  
  294. CALLING PARAMETERS:
  295.     none.
  296. ===========================================================================*/
  297. sendbrk()
  298. {
  299.     char lcrval;
  300.  
  301.         /* send break command */
  302.     lcrval = inp(lcrport); 
  303.     outp(lcrport, (lcrval | 0x40) );
  304.     sleep(10);
  305.     outp(lcrport,lcrval);
  306. } /* sendbrk */
  307.  
  308.  
  309. /****************************************************************************
  310. FUNCTION:
  311.     allow user to change port configuration manually.  This routine builds
  312.     a string which is then used to call setparams to set port mode.
  313.  
  314. CALLING PARAMETERS:
  315.     none
  316. ===========================================================================*/
  317. changecnfg()
  318. {
  319.     char option;
  320.  
  321.         /* mask of baud rate bits */
  322.     portmode = portmode & baudmask;
  323.  
  324.     printf("stop bits (1/2)? ");
  325.     option=getopt();
  326.     switch (option)
  327.     {
  328.         case '1':
  329.             portmode = portmode | stop1;
  330.             break;
  331.         case '2':
  332.         default:
  333.             portmode = portmode | stop2;
  334.     }    
  335.  
  336.     printf("\nparity (E/O/N)? ");
  337.     option=getopt();
  338.     switch (option)
  339.     {
  340.         case 'e':
  341.             portmode = portmode | even;
  342.             break;
  343.         case 'o':
  344.             portmode = portmode | odd;
  345.             break;
  346.         case 'n':
  347.         default:
  348.             portmode = portmode | nopar;
  349.     }    
  350.  
  351.     printf("\ndata bits (7/8)? ");
  352.     option=getopt();
  353.     switch (option)
  354.     {
  355.         case '7':
  356.             portmode = portmode | len7;
  357.             break;
  358.         case '8':
  359.         default:
  360.             portmode = portmode | len8;
  361.     }    
  362.     printf("\n\n");
  363.  
  364.         /* change port mode */
  365.     setmode(portmode);
  366.     display_status();
  367.  
  368. } /* changecnfg */
  369.  
  370.  
  371. /****************************************************************************
  372. FUNCTION:
  373.     returns index of findchar in string at sptr.  returns 0xffff if not
  374.     found.
  375.  
  376. CALLING PARAMETERS:
  377.     *sptr:
  378.         pointer to source string.
  379.     findchar:
  380.         character to search for.
  381. ===========================================================================*/
  382. int findb(sptr,findchar)
  383. char *sptr;
  384. char findchar;
  385.  
  386. {
  387.     int i,j;
  388.  
  389.     j = strlen(sptr);
  390.     for (i = 0; i < j; i++)
  391.     {
  392.         if (sptr[i] == findchar)
  393.             return i;
  394.     }
  395.     return 0xffff;
  396. } /* findb */
  397.  
  398.  
  399. /****************************************************************************
  400. FUNCTION:
  401.     set transmission parameters, ie baud rate, # bits, parity.  These
  402.     parameters are specified in the phone list with:
  403.             S# #stop bits
  404.             PX parity--E=even, N=none, O=odd 
  405.             D# #data bits
  406.     It expects the pointer to be set to the beginning of the data field, which
  407.     should be the phone #.
  408.  
  409. CALLING PARAMETERS:
  410.     *strptr:
  411.         pointer to string containing serial port configuration information.
  412. ===========================================================================*/
  413. setparams(strptr)
  414. char *strptr;
  415. {
  416.     int offset;
  417.  
  418.         /* skip past phone # to baud rate if present */
  419.     if ( (offset = findb(strptr,'b')) != 0xffff)
  420.     {
  421.         while (*strptr++!='b');
  422.         Baudrate = atoi(strptr);
  423.     }
  424.  
  425.         /* skip to configuration string */
  426.     while (!isspace(*++strptr));
  427.  
  428.         /* set stop bits */
  429.     if((offset = findb(strptr,'S')) != 0xffff)
  430.     {           
  431.         portmode = portmode & ~stopmask;
  432.         switch(strptr[offset+1])
  433.         {
  434.             case '1':
  435.                 portmode = portmode | stop1;
  436.                 break;
  437.             case '2':
  438.                 portmode = portmode | stop2;
  439.             default:
  440.         }
  441.     }
  442.  
  443.         /* set parity */
  444.     if((offset = findb(strptr,'P')) != 0xffff)
  445.     {           
  446.         portmode = portmode & ~parmask;
  447.         switch(strptr[offset+1])
  448.         {
  449.             case 'E':
  450.                 portmode = portmode | even;
  451.                 break;
  452.             case 'O':
  453.                 portmode = portmode | odd;
  454.                 break;
  455.             case 'N':
  456.             default:
  457.                 portmode = portmode | nopar;
  458.         }
  459.     }
  460.  
  461.         /* set data bits */
  462.     if((offset = findb(strptr,'D')) != 0xffff)
  463.     {           
  464.         portmode = portmode & ~wlenmask;
  465.         switch(strptr[offset+1])
  466.         {
  467.             case '7':
  468.                 portmode = portmode | len7;
  469.                 break;
  470.             case '8':
  471.                 portmode = portmode | len8;
  472.             default:
  473.         }
  474.     }
  475.  
  476.         /* set special flags.  Ignrx causes rxnono string test to be skipped
  477.            allowing special characters to be recieved */
  478.     if( (offset = findb(strptr,'I')) != 0xffff)
  479.         Ignrx = TRUE;
  480.     else
  481.         Ignrx = FALSE;
  482.  
  483.         /* this will set the baud and the port mode */
  484.     setbaud(Baudrate);
  485.  
  486.         /* call to setbaud will disable interrupts */
  487.     enblcm(0);
  488.  
  489.         /* pause after reset */
  490.     sleep(10);
  491. } /* setparams */
  492.  
  493.  
  494. /****************************************************************************
  495. FUNCTION:
  496.     place phone on hook by dropping DTR, causing modem to hang up.
  497.  
  498. CALLING PARAMETERS:
  499.     none.
  500. ===========================================================================*/
  501. onhook()
  502. {
  503.     char mcval;
  504.  
  505.     mcval = inp(mcrport);
  506.  
  507.         /* drop DTR to make modem hangup */
  508.     outp(mcrport, (mcval &(~dtr)) );
  509.  
  510.         /* wait till DCE goes low */
  511.     sleep (3);
  512.     printf("On Hook");
  513.  
  514. } /* onhook */
  515.  
  516.  
  517. /****************************************************************************
  518. FUNCTION:
  519.     set DTR to modem to allow auto answer, etc.  This should
  520.     set TR to modem
  521.  
  522. CALLING PARAMETERS:
  523.     none.
  524. ===========================================================================*/
  525. offhook()
  526. {
  527.     outp(mcrport, (inp(mcrport) | dtr) );
  528. } /* offhook */
  529.  
  530.  
  531.  
  532. /****************************************************************************
  533. FUNCTION:
  534.     read a char from the modem.  This routine is used by the file tranfer
  535.     routines.
  536.  
  537. CALLING PARAMETERS:
  538.     decisecs:
  539.         number of loops to wait for character
  540.  
  541. RETURNED PARAMETERS:
  542.     integer value of char read.  value will be negative if an error occurred.
  543. ===========================================================================*/
  544. readbyte(decisecs)
  545. int decisecs;
  546. {
  547.     if(MIREADY)
  548.         return MICHAR;
  549.     while(--decisecs>=0)
  550.     {
  551.         if(MIREADY)
  552.             return MICHAR;
  553.         if(CDO)
  554.             return TIMEOUT;
  555.         if(MIREADY)
  556.             return MICHAR;
  557.         if(CIREADY)
  558.         {
  559.             CICHAR;                 /* dismiss character */
  560.             return TIMEOUT;
  561.         }
  562.         if(MIREADY)
  563.             return MICHAR;
  564.  
  565.         for(Timeout=T1pause; --Timeout;)
  566.             if(MIREADY)
  567.                 return MICHAR;
  568.     }
  569.     return TIMEOUT;
  570. }
  571.  
  572.  
  573. /****************************************************************************
  574. FUNCTION:
  575.     send a string of characters to modem.
  576.  
  577. CALLING PARAMETERS:
  578.     char *sptr:
  579.         pointer to string of characters to send to modem.
  580. ===========================================================================*/
  581. sendstring(sptr)
  582. char *sptr;
  583. {
  584.     while(*sptr != '\0')
  585.     {
  586.         sendbyte(*sptr);
  587.         sptr++;     
  588.     }           
  589. } /* sendstring */           
  590.  
  591. /****************************************************************************
  592. FUNCTION:
  593.     send a char to modem.  This routine is used by the file transfer routines
  594.  
  595. CALLING PARAMETERS:
  596.     data:
  597.         char to send to modem
  598. ===========================================================================*/
  599. sendbyte(data)
  600. char data;
  601.  
  602. {
  603.     while(!MOREADY)
  604.         ;
  605.     MOCHAR(data);
  606. } /* sendbyte */
  607.  
  608.  
  609. /****************************************************************************
  610. FUNCTION:
  611.     throw away any characters input from modem.
  612.  
  613. CALLING PARAMETERS:
  614.     none.
  615. ===========================================================================*/
  616. purgeline()
  617. {
  618.     while(MIREADY)
  619.         MICHAR;
  620. }
  621.  
  622.  
  623. /****************************************************************************
  624. FUNCTION:
  625.     read the baud rate from the configuration byte.
  626.  
  627. CALLING PARAMETERS:
  628.     none
  629.  
  630. RETRUNED PARAMETERS:
  631.     unsigned value of baud rate.
  632. ===========================================================================*/
  633. readbaud()
  634. {
  635.         /* calculate baud stored in byte 5-7 */
  636.     switch(portmode & baudmask)
  637.     {
  638.         case B110:
  639.             return 110;
  640.         case B150:
  641.             return 150;
  642.         case B300:
  643.             return 300;
  644.         case B600:
  645.             return 600;
  646.         case B1200:
  647.             return 1200;
  648.         case B2400:
  649.             return 2400;
  650.         case B4800:
  651.             return 4800;
  652.         case B9600:
  653.             return 9600;
  654.         default:
  655.             printf("illegal baud rate\n");
  656.             return 0xffff;
  657.     }
  658. } /* readbaud */
  659.  
  660.  
  661.  
  662. /****************************************************************************
  663. FUNCTION:
  664.     dial phone number in phone list.  A pointer to the line containing the
  665.     phone number is passed to this routine.  The phone number must be separated
  666.     from the rest of text by a tab.  Also contained in the line are
  667.     configuration parmaters for baud rate, num of start and stop bits, etc.
  668.  
  669. CALLING PARAMETERS:
  670.     char *phoneptr:
  671.         pointer to string containing phone # to dial
  672. ===========================================================================*/
  673. dial(phoneptr)
  674. char *phoneptr;
  675. {
  676.  
  677.         /* display number */
  678.     printf("%s",phoneptr);
  679.  
  680.         /* skip to number which is marked by tab character */
  681.     while (*phoneptr != '\t')
  682.         phoneptr++;
  683.  
  684.         /* set transmission params */
  685.     setparams(phoneptr);
  686.  
  687.         /* dial the phone number */
  688.     dial_number(phoneptr);
  689.  
  690. }/* dial */
  691.  
  692.  
  693. /****************************************************************************
  694. FUNCTION:
  695.     dial phone number pointed to by phoneptr.
  696.  
  697. CALLING PARAMETERS:
  698.     char *phoneptr:
  699.         pointer to string containing phone # to dial
  700. ===========================================================================*/
  701. dial_number(phoneptr)
  702. char *phoneptr;
  703. {
  704.         /* find number, if none just quit */
  705.     while (!isdigit(*phoneptr))
  706.     {
  707.         if ((*phoneptr == '\n') || (*phoneptr == '\0'))
  708.             return;
  709.         phoneptr++;
  710.     }
  711.  
  712.         /* enable modem */
  713.     offhook();
  714.  
  715.         /* disable interrupts so command is not captured */
  716.     dsblcm();
  717.  
  718.         /* send dial command to modem, use adaptive dial */
  719.     sendstring("ATD");
  720.  
  721.         /* send number to modem until character other than
  722.            number or '-' found */
  723.     while ((isdigit(*phoneptr)) || (*phoneptr == '-'))
  724.         sendbyte(*phoneptr++);
  725.  
  726.         /* terminate command with a <CR> */
  727.     sendbyte('\r');
  728.  
  729.         /* wait for all of command to be accepted by modem to elimate
  730.            partial display on screen */
  731.     sleep(10);
  732.  
  733.         /* re-enable interrupts */
  734.     enblcm(0);
  735. }/* dial_number */
  736.