home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol158 / yam5pmmi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1984-04-29  |  9.0 KB  |  431 lines

  1. /*
  2. >>:yam5pmmi.c 12-14-83
  3.  *
  4.  * PMMI MM-103 routines installed.  These routines will:
  5.  *         * Dial the telephone
  6.  *        * Dial the telephone with ringback protocol
  7.  *          (no ring detect, just waits 8.5 seconds)
  8.  *        * Set baud rate
  9.  *        * Flip between answer and originate mode
  10.  *        * Hang up phone when appropriate
  11.  *
  12.  * Use b command (set buad) to turn on modem when dialing manually
  13.  * (for MCI, SPRINT, etc.) (works like modem7 excpt ans/org is sep
  14.  * command)
  15.  *
  16.  * 12-14-83 Moved bios() to yam7.c
  17.  *
  18.  * 10-14-83 converted to C86 syntax for 16 bit, updated to 4.26 (pjh)
  19.  *
  20.  * 8-22-83 Finally fixed ringback bug thanks to steve passe. (pjh)
  21.  *
  22.  * 7-23-82 changed to count down in "Waiting for answer" routine. (pjh)
  23.  *
  24.  * 7-10-82 Fixed error handling in waiting-for-answer routine. (pjh)
  25.  *
  26.  * 7-09-82 changed autodial routine to call terminal function directly
  27.  * after successful call. Changed set baud routine to support all baud
  28.  * rates between 61 and 710 ala cnode baud code. Fix error in dtdet()
  29.  * that caused no return. (pjh)
  30.  *
  31.  * 6-27-82 added .7 sec delay in ringback to futher try to fix bug;
  32.  * removed extra readline() code to shorten file. (pjh)
  33.  *
  34.  * 6-17-82 removed mysleep(); cleaned-up file; fixed parameter passing
  35.  * in flip(); lengthened wait time at on-hook to fix bug in ringback
  36.  * dial. (pjh)
  37.  *
  38.  * 6-13-82 added XMODEM conditional assembly defines for pause when
  39.  * flipping modem modes. Added reset to default baud in bye(). (pjh)
  40.  *
  41.  * 6-12-82 added OK and ERROR on return to yam from flip.  Deleted
  42.  * unnecessary code. (caf)
  43.  *
  44.  * based on yam5pmmi.c by joe shannon.
  45.  */
  46.  
  47. /*
  48.  * setbaud(nbaud) If legal rate, set modem registers and Baudrate
  49.  */
  50. #define EXTERN extern
  51. #include "yamc86.h"
  52.  
  53. #ifdef PMMI
  54. #define MODEMSTUFF
  55.  
  56. setbaud(nbaud)
  57. unsigned nbaud;
  58. {
  59.     if ((nbaud < 61) || (nbaud >710 )) {
  60.         printf("baudrate out of range (61-710)\n");
  61.         return(ERROR);
  62.     }
  63.     outportb(Sport+2, 15625/nbaud);
  64.  
  65.      /* turn on data terminal below 300 */
  66.     if(nbaud<301)
  67.         outportb(Sport+3,0x7F);
  68.     else     /* above 300 baud */
  69.         outportb(Sport+3,0x5F);
  70.     Baudrate=nbaud;
  71.     if(Originate) outportb(Sport,0x1D);  /* off hook originate mode */
  72.     else outportb(Sport,0x1E);    /* off hook answer mode */
  73.     sleep(CLKMHZ/2);  /*wait at least 51 msec */
  74.     outportb(Sport,0x5C); /*setup uart - 8 bits; no parity; 2 stop bits*/
  75.     return(0);
  76. }
  77. onhook()
  78. {
  79.     outportb(Sport+3,0x3F); /* idle modem */
  80.     outportb(Sport,0);      /* go onhook */
  81.     sleep(19 * CLKMHZ);     /* 3.8 sec(s) to go on */
  82. }
  83. sendbrk()
  84. {
  85.     outportb(Sport+3, 0x7B);    /* request transmit break */
  86.     sleep(CLKMHZ/2);
  87.     outportb(Sport+3, 0x7F);    /* return to normal */ 
  88.     setbaud(Baudrate);
  89. }
  90. bye()
  91. {
  92.     onhook();
  93. #ifdef DEFBAUD
  94.     Baudrate=(DEFBAUD);
  95. #else
  96.     readbaud();
  97. #endif
  98.     setbaud(Baudrate);
  99. }
  100. readbaud()
  101. {
  102. #ifdef XMODEM
  103.     Baudrate=(15625/peek(0x0040)); /* use with special bye prog */
  104. #else
  105.     Baudrate=DEFBAUD;
  106. #endif
  107. }
  108.  
  109. /*
  110.  *  flip - toggle pmmi org/ans mode
  111.  *  adapted from steve passe's cnode flip
  112.  *  Returns OK is successful, ERROR otherwise
  113.  */
  114.  
  115. flip(argc,argp)
  116. int argc;
  117. char **argp;
  118. {
  119.     if (argc != 1) {
  120.         printf("\007usage: flip 'org' or 'ans'\n");
  121.         return(ERROR);
  122.     }
  123.     if(strcmp("org", argp[0]) == 0) {
  124.         printf("changing to originate mode");
  125. #ifdef XMODEM
  126.         sleep(15*CLKMHZ/2);    /* wait a sec before you do it */
  127. #endif
  128.         outportb(Sport, 0x1d);
  129.         sleep(CLKMHZ/2);    /* kill at least 51ms. */
  130.         outportb(Sport, 0x1c);    /* enable auto hangup */
  131.         Originate = TRUE;
  132.     }
  133.     else if(strcmp("ans", argp[0]) == 0) {
  134.         printf("changing to answer mode");
  135. #ifdef XMODEM
  136.         sleep(15*CLKMHZ/2);    /* wait a sec before you do it */
  137. #endif
  138.         outportb(Sport, 0x1e);
  139.         sleep(CLKMHZ/2);    /* kill at least 51ms. */
  140.         outportb(Sport, 0x1c);    /* enable auto hangup */
  141.         Originate = FALSE;
  142.     }
  143.     else {
  144.         printf("\007? looking for 'org' or 'ans'. No action.\n");
  145.         return(ERROR);
  146.     }
  147.     return(OK);
  148. }
  149. #endif
  150.  
  151. /*
  152.  * Readline from MODEM13.C rewritten to allow much higher
  153.  * baud rates.
  154.  * Timeout is in deciseconds (1/10th's)
  155.  * For top speed, character ready is checked in many places.
  156.  * returns TIMEOUT if kbd character is ready.
  157.  *
  158.  * There are three versions of readline, the first is used if
  159.  * there is a separate register for error conditions. The second
  160.  * is used if error condx are in the same register asrx data ready.
  161.  * The last, and quickest, does not check error conditions.
  162.  */
  163.  
  164. #ifdef MIREADYERROR
  165. /* Version for 8250, 8251, 2651, etc. with all bits in one register */
  166. readline(decisecs)
  167. {
  168.     if((Mstatus=inportb(Sport))&MIREADYMASK)
  169.         goto getit;
  170.     while(--decisecs>=0) {
  171.         if((Mstatus=inportb(Sport))&MIREADYMASK)
  172.             goto getit;
  173.         if(CDO)
  174.             return TIMEOUT;
  175.         if((Mstatus=inportb(Sport))&MIREADYMASK)
  176.             goto getit;
  177. #ifndef REALSLOWKB
  178.         if(CIREADY) {
  179.             CICHAR;        /* dismiss character */
  180.             return TIMEOUT;
  181.         }
  182. #endif
  183.         if((Mstatus=inportb(Sport))&MIREADYMASK)
  184.             goto getit;
  185.         for(Timeout=T1pause; --Timeout; )
  186.             if((Mstatus=inportb(Sport))&MIREADYMASK) {
  187. getit:
  188.                 if(Mstatus&MIERRORMASK) {
  189.                     michar();        /* chuck it */
  190.                     inportb(Sport);    /* reset err bits */
  191.                     return ERROR;
  192.                 }
  193.                 else
  194.                     return michar()&Wcsmask;
  195.             }
  196.     }
  197.     return TIMEOUT;
  198. }
  199. #define READLINE
  200. #endif
  201.  
  202. #ifndef READLINE
  203. readline(decisecs)
  204. {
  205.     if(miready())
  206.         return michar()&Wcsmask;
  207.     while(--decisecs>=0) {
  208.         if(miready())
  209.             return michar()&Wcsmask;
  210.         if(CIREADY) {
  211.             CICHAR;        /* dismiss character */
  212.             return TIMEOUT;
  213.         }
  214.         if(miready())
  215.             return michar()&Wcsmask;
  216.         for(Timeout=T1pause; --Timeout; )
  217.             if(miready())
  218.                 return michar()&Wcsmask;
  219.     }
  220.     return TIMEOUT;
  221. }
  222. #endif
  223.  
  224. sendline(data)
  225. char data;
  226. {
  227.     while(!MOREADY)
  228.         ;
  229.     outportb(MODATA, data&Wcsmask);
  230. }
  231. purgeline()
  232. {
  233. #ifdef MOEMPTY
  234.     while(!MOEMPTY)
  235.         ;
  236. #endif
  237.     while(miready())
  238.         michar();
  239. }
  240.  
  241. /* pmmi autodial routines */
  242.  
  243. #ifdef AUTODIAL
  244. dial(name)
  245. char *name;
  246. {
  247.     char *s,*n, *cp, c, conflg, ringbk, rung1;
  248.     int chinp, pause;
  249.     cp = name;
  250.     ringbk = FALSE; /* ringback desired */
  251.     rung1 = FALSE;    /* if true, means we've already called once */
  252.     conflg= FALSE;
  253. dagain:    n=cisubstr(name, "\t")+1;
  254.     if((s=cisubstr(name, "\tb"))) {
  255.         printf("\n%s", name);
  256.         printf("\n<Use Control-X to abort>\n");
  257.     }
  258.     else return;
  259.     printf("Waiting for dial tone");
  260.     if(!dtdet()){
  261.         printf(" No dial tone\n");
  262.         onhook();
  263.         return;
  264.     }
  265.     printf("\nDialing -> ");
  266.     while((c=*n) != 'b') {
  267.         printf("%c",c);
  268.         if (c== 'r') ringbk = TRUE;
  269.         if (isdigit(c)) {
  270.             if(click(c) == ERROR) {
  271.             pause = 0;
  272.             goto quitnow;
  273.             }
  274.         }
  275.         ++n;
  276.     }
  277.  
  278. /* if ringback desired let ring only once (more or (less)) */
  279.  
  280.     if(ringbk && !rung1) {
  281.         printf("  One ringy dingy...\n");
  282.         /* wait 8.5 seconds for ring */
  283.         if(timer(85) == ERROR) {
  284.             setbaud(Baudrate);
  285.             goto quitnow;
  286.         }
  287.         onhook();
  288.         rung1 = TRUE;
  289.         sleep(7); /* wait a sec before dialing again */
  290.         pause = 0;
  291.         goto dagain;
  292.     }
  293.  
  294. /* number has been dialed now check for an answer */
  295.  
  296.     printf("\nWaiting for answer ");
  297.     pause=27;        /* 27 seconds */
  298.     outportb(Sport+3,0x7f);
  299.     timer(2);
  300.     outportb(Sport,0x5d);
  301.     while(inportb(Sport+2)&4) {
  302.         printf("\rWaiting for answer: %d ",pause);
  303.         if(timer(10)==ERROR) goto quitnow;
  304.         else pause--;
  305.         if (pause==0) break;
  306.     }
  307.     if(pause == 0) {
  308.         rung1 = FALSE;
  309.         ringbk = FALSE;
  310.         printf("\rHanging up...        ");
  311.         onhook();
  312.         printf("\rNo Answer !! ");
  313.         if (conflg) goto dagain;
  314.         printf(" Call again (Y/N/C)? ");
  315.         chinp=tolower(getchar());
  316.         if (chinp == 'c') {
  317.             conflg = TRUE;
  318.             goto dagain;
  319.         }
  320.         else if (chinp == 'y') goto dagain;
  321.         else return;
  322.     }
  323.     
  324.     printf("\7\n+++ Communications Established +++\7");
  325.     Originate = TRUE;
  326.     if(!setbaud(atoi(s+2)))
  327.         printf("\nBaudrate set to: %u\n", Baudrate);
  328.     if(cmdeq(cp, "cis")) Cis02=TRUE;
  329.     term();
  330.     return(OK);
  331.  
  332. quitnow: onhook();
  333.     return(OK);
  334. }    
  335.  
  336. dtdet(){
  337.     int pause;
  338.     pause=20;
  339.     outportb(Sport,1);  /* off hook */
  340.     outportb(Sport+3,0x2f); /* set det filters */
  341.     while(inportb(Sport+2)&1){
  342.         printf(".");
  343.         if(timer(3) == ERROR) pause=0;
  344.         else --pause;
  345.         if(pause==0) return(FALSE);
  346.     }
  347.     return(TRUE);
  348. }
  349.  
  350. click(num)
  351. char num;
  352. {
  353. unsigned number;
  354.     number = num - '0';
  355.     if (number == 0) number = 10;
  356.     outportb(Sport+2,PPS);
  357.     while(inportb(Sport+2) & 0x80);
  358.     while((inportb(Sport+2)&0x80)^0x80);
  359.     while (number-- ) {
  360.         outportb(Sport,1);
  361.         while(inportb(Sport+2) & 0x80);
  362.         outportb(Sport,0);
  363.         while((inportb(Sport+2)&0x80)^0x80);
  364.     }
  365.     outportb(Sport,1);
  366.     if(CIREADY) {
  367.         if((CICHAR) == 0x18) return(ERROR);
  368.     }
  369.     if(timer(5)==ERROR) return(ERROR);
  370.     return(OK);
  371. }
  372. #endif
  373.  
  374. /* uses pmmi timer function for delays.  if control-x typed while
  375.  * here, stops and returns with ERROR.
  376.  */
  377.  
  378. timer(tenths)
  379. int tenths;
  380. {
  381. int pause;
  382.         outportb(Sport+2,0xfa);  /* value for .1 sec timer pulse */
  383.         for(pause = 0;pause < tenths;pause++) {
  384.  
  385.             /* wait for timer to go low */
  386.             while(!(inportb(Sport+2)&0x80));
  387.  
  388.             if(CIREADY)
  389.                 if((CICHAR) == 0x18) return(ERROR);
  390.  
  391.             /* wait for timer to go high */
  392.             while(inportb(Sport+2)&0x80);
  393.         }
  394.         return(OK);
  395. }
  396.  
  397. /* return <> 0 if modem has character(s) ready */
  398. miready()
  399. {
  400.     return(MIREADY);
  401. }
  402.  
  403. /* return next modem character assuming miready <> 0 */
  404. michar()
  405. {
  406.     return(MICHAR);
  407. }
  408.  
  409. /* functions to output control strings to terminal */
  410. termreset()
  411. {
  412.     lputs(TERMRESET);
  413. }
  414. terminit()
  415. {
  416.     lputs(TERMINIT);
  417. }
  418. termreplot()
  419. {
  420.     lputs(TERMREPLOT);
  421. }
  422.  
  423. /*
  424.  * change modem port to n
  425.  */
  426. chngport(n)
  427. {
  428.     printf("PMMI does not support port changes.  ");
  429.     return(ERROR);
  430. }
  431.