home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / PASCAL / TPKERMIT / MODEMPRO.PAS < prev    next >
Pascal/Delphi Source File  |  1987-03-25  |  11KB  |  232 lines

  1. (* +FILE+ MODEMPRO.PASMS *)
  2. (* ================================================================= *)
  3. (*  MODEM - Routines and Global variables for IBMPC compatiables     *)
  4. (* ================================================================= *)
  5.  
  6. CONST
  7.     (* Modem Registers *)
  8.     LowOrderDiv      = 0 ;
  9.     HiOrderDiv       = 1 ;  InterruptEnable = 1 ;
  10.     InterruptIdReg   = 2 ;
  11.     LineControlReg   = 3 ;
  12.     ModemControlReg  = 4 ;
  13.     LineStatusReg    = 5 ;
  14.     ModemStatusReg   = 6 ;
  15.     ClockRate        = 18430 ;  (* CentiHertz. - use 17895 for PCjr *)
  16.     (* 8259 Interrupt Controller addresses *)
  17.     (* IC8259Reg1 = $20 ;   IC8259Reg2 = $21 ; *)
  18.  
  19.     MaxBuffsize = 20000 ;
  20.     DefaultBaud = 9600 ;
  21.  
  22. VAR
  23.     connected : boolean ;
  24.     Modem     : Integer ;
  25.     EnableMask,ResetMask : byte ;
  26.     IntVector,
  27.     Saveoffset,SaveSeg  : integer ;
  28.  
  29.     Buffer : Packed array [1..MaxBuffsize] of byte ;
  30.     Iout,Iin : integer ;
  31.  
  32. (* ------------------------------------------------------------------ *)
  33. (* IntHandler - Interrupt handler                                     *)
  34. (*            This procedure handles the modem interrupts ,           *)
  35. (*            which occur for incomming data only.                    *)
  36. (*            1. Offset 16 into this procedure must be initialize     *)
  37. (*               with the correct value of the DS register before     *)
  38. (*               using this routine.                                  *)
  39. (*            2. The routine is to start at offset 7, i.e. it         *)
  40. (*              bypasses the normal pascal entry code.                *)
  41. (*            (See InitModem Routine)                                 *)
  42. (*                                                                    *)
  43. (* ------------------------------------------------------------------ *)
  44. Procedure IntHandler  ;
  45.     (* Interrupt code starts at Inline code $50             *)
  46.     (* which is offset 7 bytes from beginning of IntHandler *)
  47.     Begin (* IntHandler *)
  48.     (* Save Registers and set up the proper DS register *)
  49.     Inline($50/$53/$51/$52/$57/$56/$06/$1E/ (* PUSH ax,bx,cx,dx,di,si,es,ds *)
  50.            $B8/$00/$00/                 (* MOV  ax,immediatevalue    *)
  51.            $50/                         (* PUSH ax                   *)
  52.            $1F/                         (* POP  ds - set ds          *)
  53.            $FB) ;                       (* STI  set interrupt enable *)
  54.  
  55.     If (Port[Modem+LineStatusReg] and $01) = $01 then
  56.          begin (* put char in buffer *)
  57.          buffer[Iin] := Port[Modem];
  58.          Iin := Iin + 1 ;
  59.          if Iin = MaxBuffsize then Iin := 1 ;
  60.          end ; (* put char in buffer *)
  61.     Port[$20] := ResetMask ;
  62.  
  63.     (* Restore the registers and Return *)
  64.     Inline ($1F/$07/$5E/$5F/$5A/$59/$5B/$58/ (* POP ds,es,si,di,dx,cx,bx,ax *)
  65.             $CF);                            (* IRET *)
  66.     End ;  (* IntHandler *)
  67.  
  68. (* ------------------------------------------------------------------ *)
  69. (* InitModem - Initialize the modem and setup interrupt procedure.    *)
  70. (*            The interrupt procedure is at IntHandler+7, and         *)
  71. (*            the DS register must be stored in IntHandler+16.        *)
  72. (*                                                                    *)
  73. (* ------------------------------------------------------------------ *)
  74.     Procedure Initmodem ;
  75.     Var rate : integer ;
  76.     Begin (* Init modem *)
  77.     If PrimaryPort then
  78.          Begin (* Primary port *)
  79.          Modem := $3F8 ;
  80.          EnableMask := $EF ;
  81.          ResetMask := $64 ;    (* end of interrupt for IRQ4 *)
  82.          IntVector := $0030 ;
  83.          End  (* Primary Port *)
  84.                   else
  85.         Begin (* Secondary Port *)
  86.         Modem := $2F8 ;
  87.         EnableMask := $F7 ;
  88.         ResetMask := $63 ;   (* end of interrupt for IRQ3 *)
  89.         IntVector := $002C ;
  90.         End ; (* Secondary Port *)
  91.     Iin := 1 ; Iout := 1 ;
  92.  
  93.     (* Initialize the Interrupt Procedure *)
  94.     Saveoffset := MemW[$0000:IntVector] ;     (* save the Old interrupt  *)
  95.     SaveSeg    := MemW[$0000:IntVector+2] ;   (* address of serial interrupt *)
  96.  
  97.     MemW[$0000:IntVector] := Ofs(IntHandler) + 7 ;  (* Use our own interrupt *)
  98.     MemW[$0000:IntVector+2] := Cseg ;               (*  hanlder              *)
  99.     MemW[Cseg:Ofs(IntHandler)+16] := Dseg ;     (* set in  for handler   *)
  100.  
  101.     Port[$21] := Port[$21] and EnableMask ;  (* Enable serial port interrupt *)
  102.     Port[$20] := ResetMask ;
  103.  
  104.     (* Initialize baud rates and bits and parity *)
  105.     Rate := round( (Clockrate/16) / (Baudrate/100)) ;
  106.     Port[Modem+LineControlReg] := $80 ;     (* Enable baud rate setting *)
  107.     Port[Modem+LowOrderDiv]    := (rate and $00FF) ;
  108.     Port[Modem+HiOrderDiv]     := rate div $100 ;
  109.     Port[Modem+LineControlReg] := (ord(Parity) shl 4) OR $0A ;
  110.                                   (* parity, 7 bits,1 stop *)
  111.     Port[Modem+ModemControlReg] := $0B ;   (* DTR and RTS *)
  112.     Port[Modem+InterruptEnable] := $01 ;   (* Data Avail. Interrupt set *)
  113.     End ; (* Init modem *)
  114.  
  115. (* ------------------------------------------------------------------ *)
  116. (*  ResetModem - Reset the Interrupt back to the original.            *)
  117. (*       Global variables - Saveoffset,SaveSeq                        *)
  118. (* ------------------------------------------------------------------ *)
  119.     Procedure ResetModem;
  120.     Begin (* Reset Modem Interrupt *)
  121.     MemW[$0000:IntVector] := Saveoffset ;    (* restore the Old interrupt    *)
  122.     MemW[$0000:IntVector+2] := SaveSeg  ;    (* address of serial interrupt *)
  123.     End; (* Reset Modem Interrupt *)
  124.  
  125. (* ------------------------------------------------------------------ *)
  126. (*  SetModem -  Set the baud rate and parity for modem.               *)
  127. (*       Global variables - Modem,Clockrate,Baudrate,Parity           *)
  128. (* ------------------------------------------------------------------ *)
  129.     Procedure SetModem ;
  130.     Var rate : integer ;
  131.     Begin (* SetModem *)
  132.     If PrimaryPort then
  133.          Begin (* Primary port *)
  134.          Modem := $3F8 ;
  135.          EnableMask := $EF ;
  136.          ResetMask := $64 ;    (* end of interrupt for IRQ4 *)
  137.          End  (* Primary Port *)
  138.                   else
  139.         Begin (* Secondary Port *)
  140.         Modem := $2F8 ;
  141.         EnableMask := $F7 ;
  142.         ResetMask := $63 ;   (* end of interrupt for IRQ3 *)
  143.         End ; (* Secondary Port *)
  144.     Rate := round( (Clockrate/16) / (Baudrate/100)) ;
  145.     Port[Modem+LineControlReg] := $80 ;     (* Enable baud rate setting *)
  146.     Port[Modem+LowOrderDiv]    := (rate and $00FF) ;
  147.     Port[Modem+HiOrderDiv]     := rate div $100 ;
  148.     Port[Modem+LineControlReg] := (ord(Parity) shl 4) OR $0A ;
  149.                                   (* parity, 7 bits,1 stop *)
  150.     End ; (* SetModem *)
  151.  
  152. (* ------------------------------------------------------------------ *)
  153. (*  DialModem - Check and waits for modem to be connected.            *)
  154. (*              It waits for DTR and CTS signals to be detected.      *)
  155. (*  Side Effect - global variable 'connected' is set true.            *)
  156. (* ------------------------------------------------------------------ *)
  157.    Procedure DialModem ;
  158.    var abyte,bbyte : byte ;
  159.    Begin (* Dial Modem *)
  160.    While ((Port[Modem+ModemStatusReg] and $30) <> $30) and DTRcheck Do
  161.          Begin (* Connect modem please *)
  162.          If audioFlag then
  163.            Begin Sound(600);delay(100);Sound(2000);delay(200); nosound;end;
  164.          writeln('  Please connect your modem ');
  165.          delay (1000);
  166.          DTRcheck := not (keychar(abyte,bbyte) and (abyte=$20)) ;
  167.          End ; (* Connect modem please *)
  168.    connected := true ;
  169.    If audioflag then
  170.        for i:=1 to 50 do begin sound(100*i);delay(5);end; nosound;
  171.    Writeln('  Connection completed ');
  172.    End ; (* Dial Modem *)
  173.  
  174. (* ------------------------------------------------------------------ *)
  175. (* RecvChar - Receive a Character from the modem port.                *)
  176. (*            TRUE - if there is a character from the modem and       *)
  177. (*                   the character is returned in the parmeter.       *)
  178. (*            FALSE - if no character found .                         *)
  179. (*                                                                    *)
  180. (* ------------------------------------------------------------------ *)
  181.     Function RecvChar (var mchar : byte) : boolean ;
  182.     Begin (* RecvChar *)
  183.     if Iin <> Iout then
  184.          begin (* get char from buffer *)
  185.          mchar := buffer[Iout] and $7F ;
  186.          Iout := Iout + 1 ;
  187.          If Iout = MaxBuffsize then Iout := 1 ;
  188.          RecvChar := true ;
  189.          if logging then
  190.                      Begin {$I-}
  191.                      write(Logfile,chr(mchar));
  192.                      If IOresult <> 0 then
  193.                         Begin (* IO error *)
  194.                         Writeln(' Disk is Full - logging teminated');
  195.                         logging := false  ;
  196.                         Close(Logfile);
  197.                         End ; (* IO error *)
  198.                      End ; {$I+}
  199.          end   (* get char from buffer *)
  200.                    else
  201.          RecvChar := false ;
  202.     End ; (* RecvChar *)
  203.  
  204. (* ------------------------------------------------------------------ *)
  205. (* SendChar - Send a character thru the modem port.                   *)
  206. (*           It waits for the previous character to be sent before    *)
  207. (*           sending the current character.                           *)
  208. (* ------------------------------------------------------------------ *)
  209.     Procedure SendChar(char : byte ) ;
  210.     Begin (* Send Char *)
  211.     While  (Port[Modem+LineStatusReg] and $20) <> $20 do delay(1);
  212.          Port[modem] := char ;
  213.     End ;  (* Send Char *)
  214.  
  215. (* ------------------------------------------------------------------ *)
  216. (* SendBreak- Send a break via the modem port .                       *)
  217. (* ------------------------------------------------------------------ *)
  218.     Procedure SendBreak ;
  219.     Var Tbyte : byte ;
  220.     Begin (* Send Break *)
  221.     Tbyte := Port[Modem+LineControlReg] ;  (* save setting *)
  222.     Port[Modem+LineControlReg] := $40 ;    (* break for 200 millsec *)
  223.     Writeln(' *** BREAK *** ');
  224.     Delay(200) ;
  225.     Port[Modem+LineControlReg] := Tbyte ;    (* restore setting *)
  226.     End ;  (* Send Break *)
  227.  
  228. (* ================================================================= *)
  229. (*    End of MODEM routines for IBMPC compatiables.                  *)
  230. (* ================================================================= *)
  231.  
  232.