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 >
Wrap
Pascal/Delphi Source File
|
1987-03-25
|
11KB
|
232 lines
(* +FILE+ MODEMPRO.PASMS *)
(* ================================================================= *)
(* MODEM - Routines and Global variables for IBMPC compatiables *)
(* ================================================================= *)
CONST
(* Modem Registers *)
LowOrderDiv = 0 ;
HiOrderDiv = 1 ; InterruptEnable = 1 ;
InterruptIdReg = 2 ;
LineControlReg = 3 ;
ModemControlReg = 4 ;
LineStatusReg = 5 ;
ModemStatusReg = 6 ;
ClockRate = 18430 ; (* CentiHertz. - use 17895 for PCjr *)
(* 8259 Interrupt Controller addresses *)
(* IC8259Reg1 = $20 ; IC8259Reg2 = $21 ; *)
MaxBuffsize = 20000 ;
DefaultBaud = 9600 ;
VAR
connected : boolean ;
Modem : Integer ;
EnableMask,ResetMask : byte ;
IntVector,
Saveoffset,SaveSeg : integer ;
Buffer : Packed array [1..MaxBuffsize] of byte ;
Iout,Iin : integer ;
(* ------------------------------------------------------------------ *)
(* IntHandler - Interrupt handler *)
(* This procedure handles the modem interrupts , *)
(* which occur for incomming data only. *)
(* 1. Offset 16 into this procedure must be initialize *)
(* with the correct value of the DS register before *)
(* using this routine. *)
(* 2. The routine is to start at offset 7, i.e. it *)
(* bypasses the normal pascal entry code. *)
(* (See InitModem Routine) *)
(* *)
(* ------------------------------------------------------------------ *)
Procedure IntHandler ;
(* Interrupt code starts at Inline code $50 *)
(* which is offset 7 bytes from beginning of IntHandler *)
Begin (* IntHandler *)
(* Save Registers and set up the proper DS register *)
Inline($50/$53/$51/$52/$57/$56/$06/$1E/ (* PUSH ax,bx,cx,dx,di,si,es,ds *)
$B8/$00/$00/ (* MOV ax,immediatevalue *)
$50/ (* PUSH ax *)
$1F/ (* POP ds - set ds *)
$FB) ; (* STI set interrupt enable *)
If (Port[Modem+LineStatusReg] and $01) = $01 then
begin (* put char in buffer *)
buffer[Iin] := Port[Modem];
Iin := Iin + 1 ;
if Iin = MaxBuffsize then Iin := 1 ;
end ; (* put char in buffer *)
Port[$20] := ResetMask ;
(* Restore the registers and Return *)
Inline ($1F/$07/$5E/$5F/$5A/$59/$5B/$58/ (* POP ds,es,si,di,dx,cx,bx,ax *)
$CF); (* IRET *)
End ; (* IntHandler *)
(* ------------------------------------------------------------------ *)
(* InitModem - Initialize the modem and setup interrupt procedure. *)
(* The interrupt procedure is at IntHandler+7, and *)
(* the DS register must be stored in IntHandler+16. *)
(* *)
(* ------------------------------------------------------------------ *)
Procedure Initmodem ;
Var rate : integer ;
Begin (* Init modem *)
If PrimaryPort then
Begin (* Primary port *)
Modem := $3F8 ;
EnableMask := $EF ;
ResetMask := $64 ; (* end of interrupt for IRQ4 *)
IntVector := $0030 ;
End (* Primary Port *)
else
Begin (* Secondary Port *)
Modem := $2F8 ;
EnableMask := $F7 ;
ResetMask := $63 ; (* end of interrupt for IRQ3 *)
IntVector := $002C ;
End ; (* Secondary Port *)
Iin := 1 ; Iout := 1 ;
(* Initialize the Interrupt Procedure *)
Saveoffset := MemW[$0000:IntVector] ; (* save the Old interrupt *)
SaveSeg := MemW[$0000:IntVector+2] ; (* address of serial interrupt *)
MemW[$0000:IntVector] := Ofs(IntHandler) + 7 ; (* Use our own interrupt *)
MemW[$0000:IntVector+2] := Cseg ; (* hanlder *)
MemW[Cseg:Ofs(IntHandler)+16] := Dseg ; (* set in for handler *)
Port[$21] := Port[$21] and EnableMask ; (* Enable serial port interrupt *)
Port[$20] := ResetMask ;
(* Initialize baud rates and bits and parity *)
Rate := round( (Clockrate/16) / (Baudrate/100)) ;
Port[Modem+LineControlReg] := $80 ; (* Enable baud rate setting *)
Port[Modem+LowOrderDiv] := (rate and $00FF) ;
Port[Modem+HiOrderDiv] := rate div $100 ;
Port[Modem+LineControlReg] := (ord(Parity) shl 4) OR $0A ;
(* parity, 7 bits,1 stop *)
Port[Modem+ModemControlReg] := $0B ; (* DTR and RTS *)
Port[Modem+InterruptEnable] := $01 ; (* Data Avail. Interrupt set *)
End ; (* Init modem *)
(* ------------------------------------------------------------------ *)
(* ResetModem - Reset the Interrupt back to the original. *)
(* Global variables - Saveoffset,SaveSeq *)
(* ------------------------------------------------------------------ *)
Procedure ResetModem;
Begin (* Reset Modem Interrupt *)
MemW[$0000:IntVector] := Saveoffset ; (* restore the Old interrupt *)
MemW[$0000:IntVector+2] := SaveSeg ; (* address of serial interrupt *)
End; (* Reset Modem Interrupt *)
(* ------------------------------------------------------------------ *)
(* SetModem - Set the baud rate and parity for modem. *)
(* Global variables - Modem,Clockrate,Baudrate,Parity *)
(* ------------------------------------------------------------------ *)
Procedure SetModem ;
Var rate : integer ;
Begin (* SetModem *)
If PrimaryPort then
Begin (* Primary port *)
Modem := $3F8 ;
EnableMask := $EF ;
ResetMask := $64 ; (* end of interrupt for IRQ4 *)
End (* Primary Port *)
else
Begin (* Secondary Port *)
Modem := $2F8 ;
EnableMask := $F7 ;
ResetMask := $63 ; (* end of interrupt for IRQ3 *)
End ; (* Secondary Port *)
Rate := round( (Clockrate/16) / (Baudrate/100)) ;
Port[Modem+LineControlReg] := $80 ; (* Enable baud rate setting *)
Port[Modem+LowOrderDiv] := (rate and $00FF) ;
Port[Modem+HiOrderDiv] := rate div $100 ;
Port[Modem+LineControlReg] := (ord(Parity) shl 4) OR $0A ;
(* parity, 7 bits,1 stop *)
End ; (* SetModem *)
(* ------------------------------------------------------------------ *)
(* DialModem - Check and waits for modem to be connected. *)
(* It waits for DTR and CTS signals to be detected. *)
(* Side Effect - global variable 'connected' is set true. *)
(* ------------------------------------------------------------------ *)
Procedure DialModem ;
var abyte,bbyte : byte ;
Begin (* Dial Modem *)
While ((Port[Modem+ModemStatusReg] and $30) <> $30) and DTRcheck Do
Begin (* Connect modem please *)
If audioFlag then
Begin Sound(600);delay(100);Sound(2000);delay(200); nosound;end;
writeln(' Please connect your modem ');
delay (1000);
DTRcheck := not (keychar(abyte,bbyte) and (abyte=$20)) ;
End ; (* Connect modem please *)
connected := true ;
If audioflag then
for i:=1 to 50 do begin sound(100*i);delay(5);end; nosound;
Writeln(' Connection completed ');
End ; (* Dial Modem *)
(* ------------------------------------------------------------------ *)
(* RecvChar - Receive a Character from the modem port. *)
(* TRUE - if there is a character from the modem and *)
(* the character is returned in the parmeter. *)
(* FALSE - if no character found . *)
(* *)
(* ------------------------------------------------------------------ *)
Function RecvChar (var mchar : byte) : boolean ;
Begin (* RecvChar *)
if Iin <> Iout then
begin (* get char from buffer *)
mchar := buffer[Iout] and $7F ;
Iout := Iout + 1 ;
If Iout = MaxBuffsize then Iout := 1 ;
RecvChar := true ;
if logging then
Begin {$I-}
write(Logfile,chr(mchar));
If IOresult <> 0 then
Begin (* IO error *)
Writeln(' Disk is Full - logging teminated');
logging := false ;
Close(Logfile);
End ; (* IO error *)
End ; {$I+}
end (* get char from buffer *)
else
RecvChar := false ;
End ; (* RecvChar *)
(* ------------------------------------------------------------------ *)
(* SendChar - Send a character thru the modem port. *)
(* It waits for the previous character to be sent before *)
(* sending the current character. *)
(* ------------------------------------------------------------------ *)
Procedure SendChar(char : byte ) ;
Begin (* Send Char *)
While (Port[Modem+LineStatusReg] and $20) <> $20 do delay(1);
Port[modem] := char ;
End ; (* Send Char *)
(* ------------------------------------------------------------------ *)
(* SendBreak- Send a break via the modem port . *)
(* ------------------------------------------------------------------ *)
Procedure SendBreak ;
Var Tbyte : byte ;
Begin (* Send Break *)
Tbyte := Port[Modem+LineControlReg] ; (* save setting *)
Port[Modem+LineControlReg] := $40 ; (* break for 200 millsec *)
Writeln(' *** BREAK *** ');
Delay(200) ;
Port[Modem+LineControlReg] := Tbyte ; (* restore setting *)
End ; (* Send Break *)
(* ================================================================= *)
(* End of MODEM routines for IBMPC compatiables. *)
(* ================================================================= *)