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

  1. /*
  2. >>:yam5smdm.c 12-14-83
  3.  *
  4.  * Smartmodem routines by Herb Schultz
  5.  *
  6.  * CompuPro Interfacer 3 / 4 serial board routines by Paul Homchick
  7.  *
  8.  * Computer Innovations C86 Version
  9.  */
  10.  
  11. #define EXTERN extern
  12. #include "yamc86.h"
  13.  
  14. #define MODEMSTUFF
  15. /*
  16.  * setbaud(nbaud) If legal rate, set modem registers and Baudrate
  17.  */
  18. setbaud(nbaud)
  19. unsigned nbaud;
  20. {
  21.     int command, baudcmd, mode0, mode1;
  22.     mode0=0xee;    /* 16x rate 2 stop bits below 300bps */
  23.     mode1=0x6e;    /* 16x rate 1 stop bit at and above 300bps */
  24.     command=0x27;
  25.     switch(nbaud) {
  26.     case   50: baudcmd=0x30;break;
  27.     case   75: baudcmd=0x31;break;
  28.     case  110: baudcmd=0x32;break;
  29.     case  134: baudcmd=0x33;break;
  30.     case  150: baudcmd=0x34;break;
  31.     case  300: baudcmd=0x35;break;
  32.     case  600: baudcmd=0x36;break;
  33.     case 1200: baudcmd=0x37;break;
  34.     case 1800: baudcmd=0x38;break;
  35.     case 2000: baudcmd=0x39;break;
  36.     case 2400: baudcmd=0x3A;break;
  37.     case 3600: baudcmd=0x3B;break;
  38.     case 4800: baudcmd=0x3C;break;
  39.     case 7200: baudcmd=0x3D;break;
  40.     case 9600: baudcmd=0x3E;break;
  41.     case 19200: baudcmd=0x3F;break;
  42.     default:
  43.         return ERROR;
  44.     }
  45.     outportb(GBI4U,MDMU);
  46.     if(nbaud<300)
  47.         outportb(GBI4M,mode0);
  48.     else
  49.         outportb(GBI4M,mode1);
  50.     outportb(GBI4M,baudcmd);
  51.     outportb(GBI4C,command);
  52.     Baudrate=nbaud;
  53.     return OK;
  54. }
  55. /* fetch the baudrate from the modem port */
  56. readbaud()
  57. {
  58. unsigned inbyt;
  59.     outportb(GBI4U,MDMU);
  60.     inportb(GBI4M)&0xFF;
  61.     inbyt=(inportb(GBI4M)&0x0f);
  62.     switch(inbyt) {
  63.     case   0: Baudrate=50;break;
  64.     case   1: Baudrate=75;break;
  65.     case   2: Baudrate=110;break;
  66.     case   3: Baudrate=134;break;
  67.     case   4: Baudrate=150;break;
  68.     case   5: Baudrate=300;break;
  69.     case   6: Baudrate=600;break;
  70.     case   7: Baudrate=1200;break;
  71.     case   8: Baudrate=1800;break;
  72.     case   9: Baudrate=2000;break;
  73.     case  10: Baudrate=2400;break;
  74.     case  11: Baudrate=3600;break;
  75.     case  12: Baudrate=4800;break;
  76.     case  13: Baudrate=7200;break;
  77.     case  14: Baudrate=9600;break;
  78.     case  15: Baudrate=19200;break;
  79.     default:
  80.         break;
  81.     }
  82.     return Baudrate;
  83. }
  84.  
  85. /* Bye hangs up the line and then resets for another call */
  86.  
  87. bye()
  88. {
  89.     onhook();
  90.     sleep(10*CLKMHZ);
  91.     setbaud(Baudrate);
  92. }
  93.  
  94.  
  95. sendbrk()
  96. {
  97.     unsigned char dp3;
  98.  
  99.     outportb(GBI4U,MDMU);
  100.     dp3=inportb(GBI4C);
  101.     outportb(GBI4C, 0x2f);    /* set line to spacing */
  102.     sleep(CLKMHZ);
  103.     outportb(GBI4C, dp3);    /* return to marking */
  104. }
  105.  
  106. #define AUTODIAL
  107. sendcmd(cp)
  108. char *cp;
  109. {
  110.     while (*cp)
  111.         sendline(*cp++);
  112. }
  113.  
  114. onhook()
  115. {
  116.     sleep(8 * CLKMHZ);
  117.     sendcmd(SMATTN);
  118.     sleep(8 * CLKMHZ);
  119.     purgeline();
  120.     sendcmd(SMHUP);
  121. }
  122.  
  123. /*
  124.  *  flip - toggle Smodem to auto-answer mode
  125.  *  Not the original intention of flip. This routine
  126.  *  hasn't been tested so tread with care.
  127.  */
  128. flip(argc,argp)
  129. int argc;
  130. char **argp;
  131. {
  132.     int rcnt,r;
  133.  
  134.     if (argc != 1) {
  135. oops:        printf("\007usage: flip [org | ans | auto]\n");
  136.         return ERROR;
  137.     }
  138.     if(strcmp("org", argp[0]) == 0 || strcmp("ans", argp[0]) == 0) {
  139.         printf("Sorry: this version of flip can't do that");
  140.         return(OK);
  141.     }
  142.     else if (strcmp("auto", argp[0]) == 0) {
  143.         puts("(^X Aborts) Waiting for Ring: ");
  144.         for (rcnt = 0; ++r <= NRING;)
  145.             if (result() > 0)
  146.                 printf("\nRing #%d", r);
  147.             else
  148.                 return(OK);
  149.         /* got the rings, go on line */
  150.         sendcmd(SMTOANS);
  151.         if (result() != OK) {
  152.             puts("\nAnswer Error\n");
  153.             return(OK);
  154.         }
  155.         Originate = FALSE;
  156.         /* You may want to turn on echo here, I haven't (yet?) */
  157.         term();
  158.         return(OK);
  159.     }
  160.     else
  161.         goto oops;
  162.     return OK;
  163. }
  164.  
  165. dial(name)
  166. char *name;
  167. {
  168.     char *ncp,*s,*n, num[40];
  169.     unsigned nbaud;
  170.  
  171.     Originate = TRUE;
  172.     ncp = name;
  173.     n=cisubstr(name, "\t")+1;
  174.  
  175.     /* I have a line "*SmodemPhones\t*" in my PHONES.T which allows me to
  176.      * do a 'call *' from the command line to have it ask for the number
  177.      */
  178.     if (*n == '*') { 
  179.         puts("Number to dial: ");
  180.         gets(num);
  181.         if (!*num)
  182.             return (OK);
  183.     }
  184.     else {
  185.         for (s = num; (*s = *n++) != '\t' && *s; ++s)
  186.             ;
  187.         *s = '\0';
  188.     }
  189.     
  190.     /* dial a * option number at the set baud rate! */
  191.     nbaud = ((s = cisubstr(name, "\tb")) ? atoi(s + 2) : Baudrate);
  192.     /* dial at 300 unless baud rate >= 1200 */
  193.     setbaud((nbaud < 1200) ? 300 : nbaud);
  194.     
  195.     purgeline();        /* dump any garbage */
  196.     sendcmd(SMATTN);
  197.     sendcmd(SMCMD);        /* use extended command set */
  198.     sendcmd(SMDIAL);
  199.     sendcmd(num);
  200.     sendline('\r');
  201.     printf("(^X aborts) Dialing -> %s\n", num);
  202.     if (result() != OK)
  203.         return (OK);
  204.     if (nbaud < 1200 && nbaud > 300)
  205.         setbaud(nbaud);    /* reset to desired baud rate */
  206.     printf("\n++ On Line ++ Baudrate = %d ++\n\7", Baudrate);
  207.     if(cmdeq(ncp,"cis")) Cis02=TRUE;
  208.     term();
  209.     return (OK);
  210. }
  211.  
  212. result()
  213. {
  214.     unsigned char rcode;
  215.     unsigned nbaud;
  216.     
  217.     sleep(10 * CLKMHZ); /* let the dial get out before allowing abort */
  218.     while (!MIREADY) {
  219.         if (CIREADY && CICHAR == '\30') {
  220.             puts("Aborting");
  221.             sendline('\r');
  222.             return (ERROR);
  223.         }
  224.     }    
  225.     switch ((rcode = MICHAR)) {
  226.       case '5':
  227.         nbaud = 1200;
  228.         setbaud(1200);
  229.       case '1':
  230.         readline(2 * CLKMHZ);    /* get rid of extra '\r' */
  231.         return (OK);
  232.       case '3':
  233.         puts("No Carrier\n");
  234.         return (ERROR);
  235.       case '2':
  236.         return (1);    /* if (result() > 0) then ring */
  237.       default:
  238.         printf("Dial error, return code = %c\n", rcode);
  239.         return (ERROR);
  240.     }
  241. }
  242.  
  243.  
  244. /*
  245.  * Readline from MODEM13.C rewritten to allow much higher
  246.  * baud rates.
  247.  * Timeout is in deciseconds (1/10th's)
  248.  * For top speed, character ready is checked in many places.
  249.  * returns TIMEOUT if kbd character is ready.
  250.  *
  251.  * There are three versions of readline, the first is used if
  252.  * there is a separate register for error conditions. The second
  253.  * is used if error condx are in the same register asrx data ready.
  254.  * The last, and quickest, does not check error conditions.
  255.  */
  256.  
  257. #ifdef MIREADYERROR
  258. /* Version for 8250, 8251, 2651, etc. with all bits in one register */
  259. readline(decisecs)
  260. {
  261.     if((Mstatus=i4rs(MDMU))&MIREADYMASK)
  262.         goto getit;
  263.     while(--decisecs>=0) {
  264.         if((Mstatus=i4rs(MDMU))&MIREADYMASK)
  265.             goto getit;
  266. #ifdef CDO
  267.         if(CDO)
  268.             return TIMEOUT;
  269. #endif
  270.         if((Mstatus=i4rs(MDMU))&MIREADYMASK)
  271.             goto getit;
  272. #ifndef REALSLOWKB
  273.         if(CIREADY) {
  274.             CICHAR;        /* dismiss character */
  275.             return TIMEOUT;
  276.         }
  277. #endif
  278.         if((Mstatus=i4rs(MDMU))&MIREADYMASK)
  279.             goto getit;
  280.         for(Timeout=T1pause; --Timeout; )
  281.             if((Mstatus=i4rs(MDMU))&MIREADYMASK) {
  282. getit:
  283.                 if(Mstatus&MIERRORMASK) {
  284.                     michar();        /* chuck it */
  285.                     inportb(Sport);    /* reset err bits */
  286.                     return ERROR;
  287.                 }
  288.                 else
  289.                     return michar()&Wcsmask;
  290.             }
  291.     }
  292.     return TIMEOUT;
  293. }
  294. #define READLINE
  295. #endif
  296.  
  297. #ifndef READLINE
  298. readline(decisecs)
  299. {
  300.     if(miready())
  301.         return michar()&Wcsmask;
  302.     while(--decisecs>=0) {
  303.         if(miready())
  304.             return michar()&Wcsmask;
  305.         if(CIREADY) {
  306.             CICHAR;        /* dismiss character */
  307.             return TIMEOUT;
  308.         }
  309.         if(miready())
  310.             return michar()&Wcsmask;
  311.         for(Timeout=T1pause; --Timeout; )
  312.             if(miready())
  313.                 return michar()&Wcsmask;
  314.     }
  315.     return TIMEOUT;
  316. }
  317. #endif
  318.  
  319. sendline(data)
  320. char data;
  321. {
  322.     while(!MOREADY)
  323.         ;
  324.     outportb(MODATA, data&Wcsmask);
  325. }
  326. purgeline()
  327. {
  328. #ifdef MOEMPTY
  329.     while(!MOEMPTY)
  330.         ;
  331. #endif
  332.     while(miready())
  333.         michar();
  334. }
  335.  
  336. /*
  337.  * change modem port to n
  338.  */
  339. chngport(n)
  340. int n;
  341. {
  342.     if(n < 0 || n > 7) {
  343.         printf("\7User request for %d out of range (0 - 7).  ",n);
  344.         return(ERROR);
  345.     }
  346.     MDMU=n;
  347.     readbaud();
  348. }
  349.  
  350. /*
  351.  * Routines to handle modem status checking and i/o
  352.  * when using Godbout Interfacer 4 board
  353.  */
  354.  
  355. #ifdef CDO
  356. /* value = 0 if carrier there
  357.  * set up to use parallel port on if4
  358.  * to monitor Cx line from modem
  359.  */
  360.  
  361. i4cd()
  362. {
  363.     outportb(GBI4U,0x06);
  364.     return((inportb(GBI4M)&0x01)-0x01);
  365. }
  366. #endif
  367.  
  368. /* read status */
  369.  
  370. i4rs(puser)
  371. unsigned char puser;
  372. {
  373.     outportb(GBI4U,puser);
  374.     return(inportb(MSTAT));
  375. }
  376.  
  377. /* read data */
  378.  
  379. i4rd(puser)
  380. unsigned char puser;
  381. {
  382.     outportb(GBI4U,puser);
  383.     return(inportb(MDATA));
  384. }
  385.  
  386. /* send data */
  387.  
  388. i4sd(puser,x)
  389. unsigned char puser,x;
  390. {
  391.     outportb(GBI4U,puser);
  392.     outportb(MDATA, x);
  393. }
  394.  
  395. #ifdef USERINIT
  396.  
  397. /* initialize special externals */
  398.  
  399. userinit()
  400. {
  401.     MDMU=MUSER;
  402. #ifdef IF3CON
  403.     CONU=CUSER;
  404. #endif
  405. }
  406. #endif
  407.  
  408. /* return <> 0 if modem has character(s) ready */
  409. miready()
  410. {
  411.     return MIREADY;
  412. }
  413.  
  414. /* return next modem character assuming miready <> 0 */
  415. michar()
  416. {
  417.     return MICHAR;
  418. }
  419.  
  420. /* functions to output control strings to terminal */
  421. termreset()
  422. {
  423.     lputs(TERMRESET);
  424. }
  425. terminit()
  426. {
  427.     lputs(TERMINIT);
  428. }
  429. termreplot()
  430. {
  431.     lputs(TERMREPLOT);
  432. }
  433.