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

    {
    From: Kai_Henningsen@ms.maus.de (Kai Henningsen)
    Newsgroups: comp.dcom.modems
    Subject: Help upgrade to 16550A
    Date: Tue, 04 Aug 92 16:13:00 GMT
    Organization: MausNet

    Any noncommercial use allowed. For commercial, ask me - or use something
    else. The ideas in this program are really very simple ... I seem to
    remember most came from an article in DDJ.
    }

    program ShowUARTs;

    uses
      m7UtilLo;

    type
      tUART           = (uNoUART, uBadUART, u8250, u16450, u16550, u16550a);

    const
      MCR             = 4;
      MSR             = 6;
      Scratch         = 7;
      FCR             = 2;
      IIR             = 2;
      LOOPBIT         = $10;

    function UARTat(UART: Word): tUART;
    var
      HoldMCR,
      HoldMSR,
      Holder          : Byte;
    begin {|UARTat}
      HoldMCR := Port[UART + MCR];
      Port[UART + MCR] := HoldMCR or LOOPBIT;
      HoldMSR := Port[UART + MSR];
      Port[UART + MCR] := $0A or LOOPBIT;
      Holder := Port[UART + MSR] and $F0;
      Port[UART + MSR] := HoldMSR;
      Port[UART + MCR] := HoldMCR and not LOOPBIT;
      if Holder <> $90 then begin
        UARTat := uNoUART;
        Exit
      end {|if Holder<>$90};
      Port[UART + Scratch] := $AA;
      if Port[UART + Scratch] <> $AA then
        UARTat := u8250
      else begin
        Port[UART + FCR] := $01;
        Holder := Port[UART + IIR] and $C0;
        case Holder of
          $C0: UARTat := u16550a;
          $80: UARTat := u16550;
          $00: UARTat := u16450;
          else UARTat := uBadUART;
        end {|case Holder};
        Port[UART + FCR] := $00;
      end {|if Port[UART+Scratch]<>$AA else};
    end {|UARTat};

    procedure DisplayUARTat(UART: Word; name: string; num: Integer);
    begin {|DisplayUARTat}
      Write(Hex(UART, 4), ' ', name, num);
      if UART = 0 then
        Writeln(' not defined')
      else
        case UARTat(UART) of
          uNoUART: Writeln(' not present');
          uBadUART: Writeln(' broken');
          u8250: Writeln(' 8250B');
          u16450: Writeln(' 16450');
          u16550: Writeln(' 16550');
          u16550a: Writeln(' 16550A');
          else Writeln(' unknown');
        end {|case UARTat(UART)};
    end {|DisplayUARTat};

    var
      i               : Integer;
      BIOSPortTab     : array [1 .. 4] of Word absolute $40: 0;
    begin {|ShowUARTs}
      Writeln; Writeln;
      Writeln('COM Port Detector');
      Writeln;
      for i := 1 to 4 do
        DisplayUARTat($02E8 + $100 * (i and 1) + $10 * Ord(i < 3), 'Standard COM',
            i);
      Writeln;
      for i := 3 to 8 do
        DisplayUARTat($3220 + $1000 * ((i - 3) div 2) + $8 * Ord(not Odd(i)),
            'PS/2 COM', i);
      Writeln;
      for i := 1 to 4 do
        DisplayUARTat(BIOSPortTab[i], 'BIOS COM', i);
    end {|ShowUARTs}.

    m7utillo is a general utility unit I use a lot; all you need is this routine:

    function Hex(v: Longint; w: Integer): String;
    var
      s               : String;
      i               : Integer;
    const
      hexc            : array [0 .. 15] of Char= '0123456789abcdef';
    begin
      s[0] := Chr(w);
      for i := w downto 1 do begin
        s[i] := hexc[v and $F];
        v := v shr 4
      end;
      Hex := s;
    end {Hex};

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