[Back to COMM SWAG index] [Back to Main SWAG index] [Original]

    {
    I've read some questions latelly with questions about how to use a com-port in
    pascal. I've written a couple of procedures for doing this. The following
    routines can be improved, for example they can be satt to run on interrupts
    and a few other thing, but... I'm not supposed to do all the job for you, am
    I??
    }

    USES CRT,DOS;

    CONST
         Com1 : WORD = 1;
         Com2 : WORD = 2;

    type
        port = object
           port: byte;
           base: word;
           baud: longint;
           inter: byte;
           function init(comport: word; baudrate: longint): boolean;
           function sendchar(c: char): boolean;
           function getchar(var c: char): boolean;
        end;

    function port.init(comport: word; baudrate: longint): boolean;
    var
       tmp: word;
       bas: word;
       test: byte;
    begin
         if odd(comport) then inter:=$C else inter:=$B;
                              {This is for later use with interrupts...}
         init:=false;
         if comport<5 then
         begin
              asm {get port base address}
                 mov bx,40h
                 mov es,bx
                 mov bx,comport
                 dec bx
                 shl bx,1
                 mov ax,es:[bx]
                 mov bas,ax
              end;
              if bas=0 then
              begin
                   writeln('Could''n find selected com-port!');
                   exit;
              end;
         end
         else
         begin
              case comport of {don't know where to find ps/2 etd
                               bios, standard base is supposed}
                5: bas:=$4220;
                6: bas:=$4228;
                7: bas:=$5220;
                8: bas:=$5228;
              end;
         end;
         base:=bas;
         tmp:=115200 div baudrate; {baudrate divisor}
         asm {lower DTS and DSR}
            mov dx,bas
            add dx,4
            xor al,al
            out dx,al
         end;
         delay(50);
         asm {raise DTS and DSR}
            mov dx,bas
            add dx,4
            mov al,11b
            out dx,al
         end;
         asm {set baudrate and N,8,1}
            mov dx,bas
            add dx,3
            mov al,10000011b {N,8,1, set baudrate divisor}
            out dx,al
            mov ax,tmp {baudrate divisor}
            mov dx,bas
            out dx,al
            inc dx
            mov al,ah
            out dx,al
            mov dx,bas
            add dx,3
            mov al,00000011b {N,8,1}
            out dx,al
         end;
         asm {interrupt enable, no interrupts enabled --> gain time}
            mov dx,bas
            inc dx
            xor al,al
            out dx,al
         end;
         asm {raise DTS and DSR}
            mov dx,bas
            add dx,4
            mov al,11b
            out dx,al
            in al,dx
            and al,11b
            mov test,al
         end;
         if test<>3 then
         begin
              writeln('Some error....');
              exit;
         end;
         init:=true;
    end;

    function port.sendchar(c: char): boolean;
    var
       bas: word;
       cts: byte;
    label
         no_send;
    begin
         cts:=0;
         bas:=base;
         asm
            mov dx,bas
            add dx,5
            in al,dx
            and al,00100000b {test CTS (Clear To Send status)}
            jz no_send
            mov cts,1
            mov dx,bas
            mov al,c
            out dx,al
         no_send:
         end;
         if cts=0 then sendchar:=false else sendchar:=true;
    end;

    function port.getchar(var c: char): boolean;
    var
       bas: word;
       rts: byte;
       c2: char;
    label
         no_data;
    begin
         rts:=0;
         bas:=base;
         asm
            mov dx,bas
            add dx,5
            in al,dx
            and al,00000001b {test for data ready}
            jz no_data
            mov rts,1
            mov dx,bas
            in al,dx
         no_data:
            mov c2,al
         end;
         c:=c2;
         if rts=0 then getchar:=false else getchar:=true;
    end;

    var
       modem: port;
       s: string;
       a: byte;
       c : Char;

    begin
         if not modem.init(com2,38400) then
         begin
              writeln('Couldn''t initialize modem...');
              halt;
         end;
         s:='atz'+#13;
         for a:=1 to length(s) do modem.sendchar(s[a]);

    end.

    If you think these routines are just great and you decide to use them as they
    are I wouldn't mind if you gave me a credit.

[Back to COMM SWAG index] [Back to Main SWAG index] [Original]