home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / beehive / zcat / ros-mdm.lbr / SMARTEAM.MZM / SMARTEAM.MDM
Text File  |  1991-01-30  |  7KB  |  249 lines

  1. { ROSMDM.INC - Remote Operating System Modem Dependent Routines }
  2.  
  3. { File:        SMARTEAM.MDM
  4.   Description: This driver is designed to support modems which use the 'AT'
  5.                command set such as the Hayes Smartmodem, the Courier 2400, and
  6.                others.  It ensures that the modem has correctly received the
  7.                command sent from the computer by monitoring the echo from the
  8.                modem.  This prevents potential problems from modems which
  9.                reset or lose characters when a call and a command are received
  10.                simultaneously.
  11.   Date:        7/28/28
  12.   Authors:     Jacques Durosier, Steve Fox
  13.   Credits:     Chris Hueuser, Richard Transue, Steve Holtzclaw
  14.  
  15.   Description: Make computer independent by using calls to channel drivers
  16.                instead of direct port accesses, comment update, and code
  17.                cleanup.
  18.   Date:        9/7/85
  19.   Author:      Mick Gaitor, Steve Fox
  20.  
  21.   Description: Improve operation.
  22.   Date:        10/26/85
  23.   Author:      Steve Fox
  24.  
  25.   Description: Use verbal result codes instead of numeric so that modems
  26.                which do not have a verbal/numeric switch can use closed loop
  27.                driver.
  28.   Date:        4/13/86
  29.   Author:      Steve Fox
  30.  
  31.   The following hardware configuration is assumed:
  32.  
  33.      DCD (pin 8)  is supported and used by the channel procedures
  34.      DTR (pin 20) is supported and used by the channel procedures
  35.      RI  (pin 22) is not supported
  36.  
  37. For the Courier 2400 and the Smarteam 1200, the switches should be set as
  38. follows:
  39.  
  40.      1 = up    DTR supported, do not force to always logic true.
  41.      2 = up    Send result codes as digits.
  42.      3 = down  Send result codes to the host.
  43.      4 = up    Echo characters when in command state.
  44.      5 = down  Do not answer the telephone.
  45.      6 = up    DCD supported, do not force to always logic true.
  46.      7 = up    Single line RJ11 telephone connection to modem.
  47.      8 = down  Enables modem command recognition when in command state.
  48.  
  49. }
  50.  
  51. const
  52.     { Modem command strings }
  53.   mdCmdInit   = 'ATH0S0=0S2=3E1X1V1Q0'^M;
  54.                { AT                   = get attention
  55.                    H0                 = ensure phone hung up
  56.                      S0=0             = disable modem auto answer function
  57.                          S2=3         = change escape code from '+' to ETX
  58.                              E1       = echo on
  59.                                X1     = extended response set
  60.                                  V1   = word response
  61.                                    Q0 = send modem responses
  62.                }
  63.   mdCmdBusy   = 'ATH1'^M;
  64.   mdCmdHangup = 'ATH'^M;
  65.   mdCmdAns    = 'ATA'^M;
  66.  
  67.     { Modem result codes }
  68.   mdRspOkay   = 'OK';                       { Command executed with no errors }
  69.   mdRspCnct3  = 'CONNECT';                  { Carrier detect at 300 bps }
  70.   mdRspRing   = 'RING';                     { Ring signal detected }
  71.   mdRspNoCar  = 'NO CARRIER';               { Carrier lost or never heard }
  72.   mdRspError  = 'ERROR';                    { Error in command execution }
  73.   mdRspCnct12 = 'CONNECT 1200';             { Carrier detect at 1200 bps }
  74.   mdRspCnct24 = 'CONNECT 2400';             { Carrier detect at 2400 bps }
  75.   mdRspOffhk  = 'OFF HOOK';                 { Modem off hook}
  76.  
  77. type
  78.   Str13       = string[13];
  79.  
  80. procedure mdQuiet;
  81. { Wait for 100 ms of silence }
  82.   var
  83.     i: integer;
  84.   begin
  85.     i := 0;
  86.     repeat
  87.       if ch_inprdy
  88.         then
  89.           begin
  90.             i := ch_inp;
  91.             i := 0
  92.           end
  93.         else
  94.           begin
  95.             delay(5);
  96.             i := succ(i)
  97.           end
  98.     until i >= 20;
  99.   end;
  100.  
  101. function mdReady(sec: integer): boolean;
  102. { Check for input from the modem }
  103.   var
  104.     ctr: integer;
  105.   begin
  106.     ctr := round(6.0 * lps);
  107.     while (not ch_inprdy) and (sec > 0) do  { Loop until ready or timeout }
  108.       begin
  109.         ctr := pred(ctr);
  110.         if ctr <= 0
  111.           then
  112.             begin
  113.               sec := pred(sec);
  114.               ctr := round(6.0 * lps)
  115.             end
  116.       end;
  117.     mdReady := sec > 0
  118.   end;
  119.  
  120. function mdReply(bt: byte; sec: integer): boolean;
  121. { Compare the input to what was sent out }
  122.   begin
  123.     if mdReady(sec)
  124.       then mdReply := bt = ch_inp
  125.       else mdReply := FALSE
  126.   end;
  127.  
  128. function mdResult: Str13;
  129. { Get result code from modem }
  130.   var
  131.     ch: char;
  132.     result: Str13;
  133.   begin
  134.     result := '';
  135.     repeat
  136.       if mdReady(5)
  137.         then ch := chr($7F and ch_inp)      { Get input }
  138.         else
  139.           begin
  140.             result := mdRspError;
  141.             ch := LF
  142.           end;
  143.       if ch in [' '..'_']
  144.         then result := result + ch;
  145.       if length(result) > 12
  146.         then delete(result, 1, 1)
  147.     until ch = LF;
  148. gotoxy (1,1);
  149.     mdResult := result
  150.   end;
  151.  
  152. function mdCommand(stg: StrPr; sec: integer): Str13;
  153. { Send a command string to the modem }
  154.   var
  155.     OK: boolean;
  156.     bt: byte;
  157.     i: integer;
  158.   begin
  159.     mdQuiet;
  160.     i := 1;
  161.     repeat
  162.       bt := ord(stg[i]);
  163.       i := succ(i);
  164.       ch_out(bt);                           { Send the character }
  165.       OK := mdReply(bt, sec)
  166.     until (not OK) or (i > length(stg));
  167.     if OK
  168.       then OK := mdReply(ord(CR), sec);
  169.     if OK
  170.       then OK := mdReply(ord(LF), sec);
  171.     if OK
  172.       then mdCommand := mdResult
  173.       else mdCommand := mdRspError
  174.   end;
  175.  
  176. procedure mdInit;
  177. { Ensure the modem is hung up, initialized, and ready to wait for a ring. }
  178.   var
  179.     tries: integer;
  180.   begin
  181.     tries := 3;
  182.     ch_init;                                { Initialize the remote channel }
  183.     ch_on;
  184.     ch_set(300);                            { Set the channel speed }
  185.     repeat
  186.       tries := pred(tries)
  187.     until (mdCommand(mdCmdInit, 5) = mdRspOkay) or (tries <= 0);
  188.     mdQuiet
  189.   end;
  190.  
  191. procedure mdBusy;
  192. { Take modem off hook to present a busy signal to incoming callers }
  193.   var
  194.     tries: integer;
  195.   begin
  196.     tries := 3;
  197.     repeat
  198.       tries := pred(tries)
  199.     until (mdCommand(mdCmdBusy, 5) = mdRspOkay) or (tries <= 0)
  200.   end;
  201.  
  202. procedure mdHangup;
  203. { Hangup modem }
  204.   var
  205.     i, tries: integer;
  206.     result: Str13;
  207.   begin
  208.     tries := 3;
  209.     repeat
  210.       ch_off;
  211.       delay(500);
  212.       ch_on;
  213.       if ch_carck
  214.         then
  215.           begin
  216.             delay(1000);
  217.             for i := 1 to 3 do
  218.               ch_out(ord(ETX));
  219.             delay(1000);
  220.             result := mdCommand(mdCmdHangup, 5)
  221.           end;
  222.       tries := pred(tries)
  223.     until not ch_carck or (tries <= 0)
  224.   end;
  225.  
  226. function mdRing: boolean;
  227. { Determine if the phone is ringing }
  228.   begin
  229.     if ch_inprdy
  230.       then mdRing := mdResult = mdRspRing
  231.       else mdRing := FALSE
  232.   end;
  233.  
  234. procedure mdAns;
  235. { Answer call and set system to correct baud rate }
  236.   var
  237.     result: Str13;
  238.   begin
  239.     result := mdCommand(mdCmdAns, 35);      { Let the modem answer }
  240.     if result = mdRspCnct3
  241.       then ch_set(300)
  242.     else if result = mdRspCnct12
  243.       then ch_set(1200)
  244. (*  else if result = mdRspCnct24
  245.       then ch_set(2400)
  246. *)    else mdHangup;
  247.     mdQuiet
  248.   end;
  249.