home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / ros / ros-mac.lbr / OSB-EXEC.IQC / OSB-EXEC.INC
Encoding:
Text File  |  1986-07-28  |  10.8 KB  |  374 lines

  1. { ROSMAC.INC for the OSBORNE EXEC and Hayes Smart Modem 1200   }
  2.  
  3. (* THIS IS NOT A FINISHED OVERLAY. Fix me! fix me! rename to rosmac.inc and
  4. compile with ros32a. It will answer the phone the first time
  5. because I places the ATS0=1 which it shouldn't need but it doesn't reset
  6. properly and just hangs when somebody hangs up. I took addresses from the
  7. Osborne Exec Mex overlay which seems to initialize the port properly. It seems
  8. like the problem is in the hangup routine. I have noticed that if I pull the
  9. rs232 plug out of the machine the program resets like it is ready for another
  10. call but it won't answer a second call. The  date routine works fine to
  11. get the date but not to set the date. I have not removed some of the kaypro
  12. stuff that this file was based on.
  13. If you can fix this overlay please upload to george's board or my board
  14. george  1-717-657-8699         my POWER board 1-608-251-3494
  15. thanks   maurice thaler  voice 608-244-8517    *)
  16.   YEAR,HOUR,MINUTE,SECOND,DAY,MONTH  : BYTE;   {CPM+TIME STUFF}
  17.   JULDATE : INTEGER;
  18.      {** Time and date routines }
  19. PROCEDURE JulToDay(Year : Byte;  JulDate : INTEGER;   VAR Month, Day : Byte);
  20. CONST DaysInMonth = ' 312831303130313130313031';
  21. VAR   DayInMon,
  22.       ResCode  : INTEGER;
  23.       Finished : BOOLEAN;
  24. BEGIN Month    := 1;
  25.       Finished := false;
  26.       WHILE NOT Finished DO  BEGIN
  27.           VAL(COPY(DaysInMonth, 2*Month, 2), DayInMon, ResCode);
  28.           IF (Month = 2) THEN  BEGIN
  29.                IF ((Year MOD 4) = 0) THEN DayInMon := DayInMon + 1
  30.           END;
  31.           IF (JulDate <= DayInMon) THEN
  32.                      Finished := true
  33.           ELSE BEGIN JulDate  := JulDate - DayInMon;
  34.                      Month    := Month + 1
  35.                END
  36.       END;
  37.       Day := JulDate
  38. END;
  39.  
  40. PROCEDURE CPMtoJulian(CPMdate : INTEGER;   VAR Year : Byte;  VAR JulDate : INTEGER);
  41. CONST BaseYear = 78;
  42. BEGIN Year    := CPMdate DIV 365;
  43.       JulDate := (CPMdate MOD 365) - ((Year+1) DIV 4);
  44.       Year    := Year + BaseYear
  45. END;
  46.  
  47. PROCEDURE GetTimeAndDate(VAR Year    : Byte;
  48.                          VAR JulDate : INTEGER;
  49.                          VAR Hour,
  50.                              Minute,
  51.                              Second  : Byte);
  52. CONST TimeAndDate  = 105;
  53. VAR   TimeDate     : RECORD DateInt  : INTEGER;
  54.                             HourByte : Byte;
  55.                             MinByte  : Byte
  56.                      END;
  57.  
  58. FUNCTION BCDtoBIN(BCD : Byte) : Byte;
  59.    BEGIN BCdtoBIN := 10 * (BCD DIV 16) + (BCD MOD 16)
  60.    END;
  61.  
  62. BEGIN Second := BCDtoBIN(BDos(105, Addr(TimeDate)));
  63.       WITH TimeDate DO  BEGIN
  64.             Minute := BCDtoBIN(MinByte);
  65.             Hour   := BCDtoBIN(HourByte);
  66.             CPMtoJulian(DateInt, Year, JulDate)
  67.       END
  68. END;
  69.  
  70. procedure GetTAD(var t: tad_array);
  71. { Return a 6 element integer array of the current system time in
  72.   seconds, minutes, hours, day, month, and year. }
  73. begin
  74. gettimeanddate (year,juldate,hour,minute,second);
  75.   jultoday (year,juldate,month,day);
  76.   t[0] := second;
  77.   t[1] := minute;
  78.   t[2] := hour;
  79.   t[3] := day;
  80.   t[4] := month;
  81.   t[5] := year
  82. end;
  83.  
  84. (* procedure GetTAD(var t: tad_array);
  85. { Return a 6 element byte array of the current system time in
  86.   seconds, minutes, hours, day, month, and year. }
  87.   var
  88.     i    : integer;
  89.     Time : array [0..12] of byte;           { Array filled in from Z-Clock }
  90.   begin
  91.     for i := 0 to 12 do                     { This section reads the Z-Clock }
  92.       Time[i] := port[BasePort + i];
  93.     t[0] := Time[1] * 10 + Time[0];
  94.     if Time[5] < 4
  95.       then t[2] := Time[5] * 10 + Time[4]
  96.     else if Time[5] >= 8
  97.       then t[2] := (Time[5] - 8) * 10 + Time[4]
  98.       else t[2] := (Time[5] - 4) * 10 + Time[4];
  99.     t[1] := Time[3] * 10 + Time[2];
  100.     if Time[8] >= 4
  101.       then Time[8] := Time[8] - 4;
  102.     t[3] := Time[8] * 10 + Time[7];
  103.     t[4] := Time[10] * 10 + Time[9];
  104.     t[5] := Time[12] * 10 + Time[11]
  105.   end;
  106.   *)
  107. procedure SetTAD(var t: tad_array);
  108. { Set the system time using  a 6 element byte array }
  109.   var
  110.     i    : integer;
  111.     Time : array [0..12] of byte;           { Array filled in from Z-Clock }
  112.   begin
  113.     Time[0] := 0;
  114.     Time[1] := 0;
  115.     Time[2] := t[1] mod 10;
  116.     Time[3] := t[1] div 10;
  117.     Time[4] := t[2] mod 10;
  118.     Time[5] := t[2] div 10;
  119.     Time[6] := 0;                           { Day of week computed in ROS }
  120.     Time[7] := t[3] mod 10;
  121.     Time[8] := t[3] div 10;
  122.     Time[9] := t[4] mod 10;
  123.     Time[10]:= t[4] div 10;
  124.     Time[11]:= t[5] mod 10;
  125.     Time[12]:= t[5] div 10;
  126.     For i := 0 to 12 do
  127.     {  port[BasePort + i] := Time[i]  }
  128.   end;
  129.  
  130.  
  131. procedure SpecialBell(bell_on: boolean);
  132. { Signal sysop from chat with special bell (if available) }
  133. begin
  134.   if bell_on
  135.     then port[$C8] := $0F
  136.     else port[$C8] := $07
  137. end;
  138.  
  139. const
  140. { Machine specific constants }
  141.  
  142.   DataPort   = $0C;          { Data port }
  143.   StatusPort = $0D;          { Status port }
  144.   RatePort   = $04;          { Data rate (bps) port }
  145.  
  146.   RESCHN     = $18;          { reset channel }
  147.   RESSTA     = $14;          { reset ext/status }
  148.   WRREG1     = $00;          { value to write to register 1 }
  149.   WRREG3     = $C1;          { 8 bits/char, rx enable }
  150.   WRREG4     = $44;          { 16x, 1 stop bit, no parity }
  151.   DTROFF     = $68;          { dtr off, rts off }
  152.   DTRON      = $EA;          { dtr on, 8 bits/char, tx enable, rts on }
  153.   ONINS      = $30;          { error reset }
  154.  
  155. { StatusPort status masks }
  156.  
  157.   DAV        = $01;          { data available }
  158.   TRDY       = $04;          { transmit buffer empty }
  159.   DCD        = $20;          { data carrier detect }
  160.   PE         = $10;          { parity error }
  161.   OE         = $20;          { overrun error }
  162.   FE         = $40;          { framing error }
  163.   ERR        = $60;          { parity, overrun and framing error }
  164.  
  165. { Smartmodem result codes }
  166.  
  167.   OKAY        = '0';         { Command executed with no errors }
  168.   CONNECT300  = '1';         { Carrier detect at 300 bps }
  169.   RING        = '2';         { Ring signal detected }
  170.   NOCARRIER   = '3';         { Carrier lost or never heard }
  171.   ERROR       = '4';         { Error in command execution }
  172.   CONNECT1200 = '5';         { Carrier detect at 1200 bps }
  173.  
  174. { Rate setting commands }
  175.   BDSET1200  = $47;
  176.   BDSET300   =  $1;
  177.   BD300      = $80;            { 300 bps }
  178.   BD1200     = $60;            { 1200 bps }
  179.  
  180. procedure putstat(st: StrStd);
  181. { Put 'st' on status line and return to normal display }
  182.   const
  183.     status_line    =  1;                    { Line used for system status }
  184.     last_line      = 24;                    { Last line on screen }
  185.   begin
  186.     GotoXY(1, status_line);
  187.     ClrEol;
  188.     LowVideo;
  189.     write(st);
  190.     HighVideo;
  191.     GotoXY(1, last_line)
  192.   end;
  193.  
  194. procedure mdout(b: byte);
  195. { Output a byte to modem - wait until ready }
  196. begin
  197.   repeat
  198.   until ((TRDY and port[StatusPort]) <> 0);
  199.   port[DataPort] := b
  200. end;
  201.  
  202. function mdinp: byte;
  203. { Input a byte from modem - no wait - assumed ready }
  204. const
  205.   NOPAR = $7F;
  206. var
  207.   bt: byte;
  208. begin
  209.   bt := port[DataPort];
  210.   mdinp := NOPAR and bt
  211. end;
  212.  
  213.  
  214. procedure mdsend(mstr: StrStd;lstr: Integer);
  215. { Send a command string to the modem w/ CR and delay }
  216. var
  217.   i           :  integer;
  218.   bt          :  byte;
  219. begin
  220.   for i := 1 to lstr do
  221.   begin
  222.     bt := ord(mstr[i]);
  223.     mdout(bt)
  224.   end;
  225.   bt := ord(CR);
  226.   mdout(bt);
  227.   delay(2000);
  228. end;
  229.  
  230.  
  231. procedure mdinit;
  232. { Initialize the sio channel and the Hayes Smartmodem 1200 }
  233. const
  234.   sio_init: array[1..9] of byte = (RESCHN, 4, WRREG4, 1, WRREG1, 3, WRREG3, 5, DTROFF);
  235. var
  236.   i: integer;
  237.   mdmstr   : StrStd;
  238.   bt       : byte;
  239. begin
  240.   for i := 1 to 9 do
  241.     port[StatusPort] := sio_init[i];        { initialize the SIO channel }
  242.   port[StatusPort] := 5;                    { pull DTR high }
  243.   port[StatusPort] := DTRON;
  244.   { port[RatePort] := BDSET1200;}
  245.    port[RatePort] := BD1200;                 {set the ZSIO to 1200 baud}
  246.   delay (500);                         {let the modem settle for a bit}
  247.   mdmstr := 'ATZ';
  248.   mdsend(mdmstr,3);
  249.   mdmstr := 'AT';
  250.   mdsend(mdmstr,2);            {force the modem to 1200 baud}
  251.   mdmstr :=  'ATE0Q0V0M0X1 S0=1 S2=3 S4=255 S5=255';
  252.   mdsend(mdmstr,41);
  253.   bt := mdinp;                              { clear any previous rings }
  254.   bt := mdinp
  255. end;
  256.  
  257. function mdinprdy: boolean;
  258. { Check for ready to input from modem }
  259. var
  260.   bt: byte;
  261. begin
  262.   if ((DAV and port[StatusPort]) <> 0) then
  263.     begin
  264.       port[StatusPort] := 1;
  265.       if ((ERR and port[StatusPort]) <> 0) then
  266.         begin
  267.           port[StatusPort] := ONINS;
  268.           bt := port[DataPort];
  269.           mdinprdy := FALSE
  270.         end
  271.       else mdinprdy := TRUE
  272.     end
  273.   else mdinprdy := FALSE
  274. end;
  275.  
  276. function mdring: boolean;
  277. { Determine if the phone is ringing }
  278. var
  279.   code: char;
  280. begin
  281.   if mdinprdy then
  282.     begin
  283.       code := chr(mdinp);
  284.       if code = RING then mdring := TRUE
  285.       else mdring := FALSE
  286.     end
  287.   else mdring := FALSE
  288. end;
  289.  
  290.  
  291. function mdcarck: boolean;
  292. { Check to see if carrier is present }
  293. begin
  294.   port[StatusPort] := RESSTA;
  295.   mdcarck := ((DCD and port[StatusPort]) <> 0)
  296. end;
  297.  
  298.  
  299. procedure mdhangup;
  300. { Hangup modem }
  301. var
  302.   mdmstr   : StrStd;
  303. begin
  304.  { repeat }
  305.     port[StatusPort] := 5;             { setup to write register 5 }
  306.     port[StatusPort] := DTROFF;        { clear DTR, causing hangup }
  307.     delay(2000);
  308.     port[StatusPort] := 5;
  309.     port[StatusPort] := DTRON;
  310.    if mdcarck then
  311.       begin
  312.         mdmstr := chr(3)+chr(3)+chr(3);
  313.         mdsend(mdmstr,3);             { get modems attention }
  314.         mdmstr := 'ATH0';
  315.         mdsend(mdmstr,4);             { hang up phone }
  316.       end;
  317.   until not mdcarck
  318. end;
  319.  
  320. procedure mdans;
  321. { Detect and set system to rate at which modem answered phone }
  322. var
  323.   mdmstr   : StrStd;
  324.   code     : char;
  325.   bt       : byte;
  326. begin
  327.   repeat
  328.   until mdinprdy;
  329.   bt := mdinp;
  330.   mdmstr := 'ATA';
  331.   mdsend(mdmstr,3);
  332.   repeat
  333.   until mdinprdy;
  334.   code := chr(mdinp);
  335.   if code = CONNECT1200 then
  336.     begin
  337.       port[RatePort] := BDSET1200;
  338.      port[RatePort] := BD1200;
  339.       rate := {50;}$60;
  340.       delay(500);
  341.       bt := mdinp;
  342.       bt := mdinp
  343.     end;
  344.   if code = CONNECT300 then
  345.     begin
  346.       port[RatePort] := BDSET300;
  347.       port[RatePort] := BD300;
  348.       rate :={ 200;} $180;
  349.       delay(500);
  350.       bt := mdinp;
  351.       bt := mdinp
  352.     end;
  353.   if code = NOCARRIER then mdhangup
  354. end;
  355.  
  356. procedure system_init;
  357. { System particular initialization to be done once (when ROS first starts) }
  358.   begin
  359.   end;
  360.  
  361.  
  362.  
  363. procedure mdbusy;
  364. { Take modem off hook to present a busy signal to incoming callers }
  365. var
  366.   mdmstr :  String[4];
  367. begin
  368.   mdmstr := 'ATH1'; { take modem off hook to give busy signal }
  369.   mdsend(mdmstr,4);
  370. end;
  371. ar
  372.   mdmstr :  String[4];
  373. begin
  374.   mdmstr := 'ATH1'; { take modem off