home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / bbs / pics-ap2.lbr / APPLESM.MZM / APPLESM.MDM
Encoding:
Text File  |  1987-06-04  |  6.4 KB  |  202 lines

  1. { ROS.MDM - Remote Operating System Modem Dependent Routines }
  2.  
  3. { File:        APPLE-SM.MDM
  4.   Description: Driver for Apple with External Modem 'AT' compatible
  5.   Date:        5/24/87
  6.   Author       David Leffler
  7.   Credits      See Below
  8.  
  9.   Extracted:   SM12.MDM
  10.   Description: This driver set is designed to support 'AT' compatible modems.
  11.   Date:        7/28/85
  12.   Authors:     Jacques Durosier, Steve Fox
  13.   Credits:     Chris Hueuser, Richard Transue, Steve Holtzclaw
  14.  
  15.   Description: Small changes made, including default to 1200 baud operation.
  16.   Date:        9/1/85
  17.   Author:      Mick Gaitor
  18. }
  19. {** Modem drivers **}
  20.  
  21. { This driver is designed to support modems which use the 'AT' command set
  22.   such as the Hayes Smartmodem, the Courier 2400, and others.   It ensures
  23.   that the modem has correctly received the command sent from the computer
  24.   by monitoring the echo from the modem.  This prevents potential problems
  25.   from modems which reset or lose characters when a call and a command are
  26.   received simultaneously.
  27.  
  28.   The following hardware configuration is assumed:
  29.  
  30.      DCD (pin 8) is supported
  31.      DTR (pin 20) is supported
  32.      RI  (pin 22) is not supported
  33.  
  34. The following modem default switches are assumed:
  35.  
  36.      1 = up    DTR supported, do not force to always logic true.
  37.      2 = down  Send result codes as digits when in command state.
  38.                (If using ROSQX.MCH, this switch position doesn't matter - [MAG])
  39.      3 = down  Result codes are sent to the terminal.
  40.      4 = up    Echo characters when in command state.
  41.      5 = down  Do not answer the telephone.
  42.      6 = up    DCD supported, do not force to always logic true.
  43.      7 = up    Single line RJ11 telephone connection to modem.
  44.      8 = down  Enables modem command recognition when in command state.
  45. }
  46.  
  47. {  To get this to work on an External Modem off an Apple // some changes
  48. had to be made.  First all External modems have a continuous carrier so the
  49. check for carrier would hang the program.  Second the modem initializer must
  50. set the modem for numeric return codes since mdresult won't work unless it
  51. gets numbers.
  52.  
  53.   You may have to set some of the modem strings (i.e. Md_init or any others
  54. that send straight Hayes Compatable type commands) to your particular Modem.
  55. }
  56.  
  57. const
  58.  
  59. { Modem result codes }
  60.  
  61.   OKAY        =  '0';                       { Command executed with no errors }
  62.   CONNECT300  =  '1';                       { Carrier detect at 300 bps }
  63.   RING        =  '2';                       { Ring signal detected }
  64.   NOCARRIER   =  '3';                       { Carrier lost or never heard }
  65.   ERROR       =  '4';                       { Error in command execution }
  66.   CONNECT1200 =  '5';                       { Carrier detect at 1200 bps }
  67.   CONNECT2400 = '10';                       { Carrier detect at 2400 bps }
  68.  
  69. function mdresult: Str3;
  70. { Get result code from modem }
  71.   var
  72.     count: integer;
  73.     ch: char;
  74.     result: Str3;
  75.   begin
  76.     result := '';
  77.     repeat
  78.       repeat
  79.       until ch_inprdy;
  80.       ch := chr(ch_inp);
  81.       if ch in ['0'..'9']
  82.         then result := result + ch;
  83.       if length(result) > 2
  84.         then delete(result, 1, 1)
  85.     until ch = CR;
  86.     mdresult := result
  87.   end;
  88.  
  89. procedure mdsend(st: StrStd);
  90. { Send a command string to the modem and continue sending until the modem
  91.   echoes exactly what was sent. }
  92.   var
  93.     bt: byte;
  94.     i, j: integer;
  95.   begin
  96.     repeat
  97.       while ch_inprdy do                    { Clear any inputs }
  98.         begin
  99.         bt := ch_inp;
  100.         end;
  101.       i := 1;
  102.       repeat
  103.         bt := ord(st[i]);
  104.         ch_out(bt);                         { Send the character }
  105.         j := 500;
  106.         repeat                              { Loop until ready or timeout }
  107.           j := pred(j)
  108.         until ch_inprdy or (j <= 0);
  109.         OK := ((bt = ch_inp) and (j > 0));  { Check for correct echo }
  110.         i := succ(i)
  111.       until (not OK) or (i > length(st));
  112.     until OK;
  113.   end;
  114.  
  115. procedure mdhangup;
  116. { Hangup modem }
  117.   var
  118.     i: integer;
  119.   begin
  120.       { Break before disconnect not implemented }
  121.       ch_off;                               { Hangup NOW! }
  122.       delay(1000);
  123.       ch_on;
  124.           for i := 1 to 3 do
  125.             ch_out(ord(ETX));
  126.           delay(1500);
  127.           repeat
  128.             mdsend('AT H0'+CR)
  129.           until mdresult = OKAY;
  130.   end;
  131.  
  132. procedure mdbusy;
  133. { Take modem off hook to present a busy signal to incoming callers }
  134.   begin
  135.     repeat
  136.       mdsend('AT H1M0'+CR)
  137.       { NOTE: 'M0' must be last command on line in order to work }
  138.       { properly on the Prometheus ProModem 1200  [MAG]          }
  139.     until mdresult = OKAY
  140.   end;
  141.  
  142. function mdring: boolean;
  143. { Determine if the phone is ringing }
  144.   begin
  145.     if ch_inprdy
  146.       then mdring := (RING = mdresult)
  147.       else mdring := FALSE
  148.   end;
  149.  
  150. procedure mdans;
  151. { Detect and set system to rate at which modem answered phone }
  152.   var
  153.     bt: byte;
  154.     result: Str3;
  155.   begin
  156.     Write('');
  157.     mdsend('AT A'+CR);
  158.     result := mdresult;
  159.     { Why not CASE here? }
  160.     if result = CONNECT300                  { Reformatted stmt  [MAG] }
  161.     then
  162.       ch_set(300)
  163.     else
  164.       if result = CONNECT1200
  165.       then
  166.         ch_set(1200)
  167. (* Un-comment this if you can handle 2400 baud --
  168.       else
  169.         if result = CONNECT2400
  170.         then
  171.           ch_set(2400)
  172. *)
  173.         else
  174.           mdhangup;
  175.     delay(500);                             { Make sure carrier is stable }
  176.     while ch_inprdy do                      { Clear any inputs }
  177.       bt := ch_inp;
  178.   end;
  179.  
  180. procedure mdinit;
  181. { Ensure the modem is hung up, initialized, and ready to wait for a ring. }
  182.   var
  183.     bt: byte;
  184.   begin
  185.     ch_init;                                { Initialize the remote channel }
  186.     ch_on;
  187.     ch_set(1200);                           { Set the channel speed }
  188. (* Un-comment this if you can handle 2400 baud --
  189.    If so, don't forget to remove the "ch_set(1200);" above...
  190.     ch_set(2400);                           { Set the channel speed }
  191. *)
  192.     repeat
  193.       mdsend('AT V0'+CR);                 { Make modem return numeric codes }
  194.     until mdresult = OKAY;
  195.     repeat
  196.       mdsend('AT X2 H0 M0 S2=3' + CR);   { Set Apple Personal Modem Extended Codes }
  197.     until mdresult = OKAY;
  198.     while ch_inprdy do                      { Clear any inputs }
  199.       bt := ch_inp;
  200.   end;
  201.  
  202.