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

    unit CaseUtil;

    interface

    type
      DelimType =
        record
          thousands,
          decimal,
          date,
          time           : array[0..1] of Char;
        end;

      CurrType       = (leads,             { symbol precedes value }
                        trails,            { value precedes symbol }
                        leads_,            { symbol, space, value }
                        _trails,           { value, space, symbol }
                        replace);          { replaced }

      CountryType =
        record
          DateFormat     : Word;           { 0: USA, 1: Europe, 2: Japan }
          CurrSymbol     : array[0..4] of Char;
          Delimiter      : DelimType;      { Separators }
          CurrFormat     : CurrType;       { Way currency is formatted }
          CurrDigits     : Byte;           { Digits in currency }
          Clock24hrs     : Boolean;        { True if 24-hour clock }
          CaseMapCall    : procedure;      { Lookup table for ASCII > $80 }
          DataListSep    : array[0..1] of Char;
          CID            : word;
          Reserved       : array[0..7] of Char;
        end;

      CountryInfo =
        record
          case InfoID: byte of
          1: (IDSize     : word;
              CountryID  : word;
              CodePage   : word;
          TheInfo    : CountryType);
          2: (UpCaseTable: pointer);
          end;

    var
      CountryOk : Boolean;            { Could determine country code flag }
      CountryRec    : CountryInfo;

    function Upcase(c : Char) : Char;
    function LoCase(c : Char) : Char;
    function UpperStr(s : string) : string;
    function LowerStr(s : string) : string;
    procedure UpCaseStr(var s : String);
    procedure LoCaseStr(var s : String);

    implementation

    {$R-,S-,V- }
    var
      LoTable   : array[0..127] of byte;
      CRP, LTP  : pointer;

      { Convert a character to upper case }
      function Upcase; Assembler; asm
        mov     al, c
        cmp     al, 'a'
        jb      @2
        cmp     al, 'z'
        ja      @1
        sub     al, ' '
        jmp     @2
    @1: cmp     al, 80h
        jb      @2
        sub     al, 7eh
        push    ds
        lds     bx,CountryRec.UpCaseTable
        xlat
        pop     ds
    @2:
      end;                                 { UpCase }

      { Convert a character to lower case }
      function LoCase; Assembler;  asm
        mov     al, c
        cmp     al, 'A'
        jb      @2
        cmp     al, 'Z'
        ja      @1
        or      al, ' '
        jmp     @2
    @1: cmp     al, 80h
        jb      @2
        sub     al, 80h
        mov     bx,offset LoTable
        xlat
    @2:
      end;                                 { LoCase }

      { Convert a string to uppercase }
      procedure UpCaseStr; Assembler;  asm
        cld
        les     di, s
        xor     ax, ax
        mov     al, es:[di]
        stosb
        xchg    ax, cx
        jcxz    @4
        push    ds
        lds     bx,CountryRec.UpCaseTable
    @1: mov     al, es:[di]
        cmp     al, 'a'
        jb      @3
        cmp     al, 'z'
        ja      @2
        sub     al, ' '
        jmp     @3
    @2: cmp     al, 80h
        jb      @3
        sub     al, 7eh
        xlat
    @3: stosb
        loop    @1
        pop     ds
    @4:
      end;                                 { UpCaseStr }

      { Convert a string to lower case }
      procedure LoCaseStr; Assembler;  asm
        cld
        les     di, s
        xor     ax, ax
        mov     al, es:[di]
        stosb
        xchg    ax, cx
        jcxz    @4
    @1: mov     al, es:[di]
        cmp     al, 'A'
        jb      @3
        cmp     al, 'Z'
        ja      @2
        or      al, ' '
        jmp     @3
    @2: cmp     al, 80h
        jb      @3
        sub     al, 80h
        mov     bx, offset LoTable
        xlat
    @3: stosb
        loop    @1
    @4:
      end;                                 { LoCaseStr }

    function UpperStr(s : string) : string;
    begin  UpCaseStr(s);  UpperStr:=s end;
    function LowerStr(s : string) : string;
    begin  LoCaseStr(s);  LowerStr:=s end;

    begin                                  { init DoCase unit }
      CRP := @CountryRec;
      LTP := @LoTable;
      asm

        { Exit if Dos version < 3.0 }
        mov     ah, 30h
        int     21h
        cmp     al, 3
        jb      @1

        { Call Dos 'Get country dependent information' function }
        mov     ax, 6501h
        les     di, CRP
        mov     bx,-1
        mov     dx,bx
        mov     cx,41
        int     21h
        jc      @1

        { Call Dos 'Get country dependent information' function }
        mov     ax, 6502h
        mov     bx, CountryRec.CodePage
        mov     dx, CountryRec.CountryID
        mov     CountryRec.TheInfo.CID, dx
        mov     cx, 5
        int     21h
        jc      @1

        { Build LoCase table }
        les     di, LTP
        mov     cx, 80h
        mov     ax, cx
        cld
    @3:
        stosb
        inc     ax
        loop    @3
        mov     di, offset LoTable - 80h
        mov     cx, 80h
        mov     dx, cx
        push    ds
        lds     bx, CountryRec.UpCaseTable
        sub     bx, 7eh
    @4:
        mov     ax, dx
        xlat
        cmp     ax, 80h
        jl      @5
        cmp     dx, ax
        je      @5
        xchg    bx, ax
        mov     es:[bx+di], dl
        xchg    bx, ax
    @5:
        inc     dx
        loop    @4
        pop     ds
        mov     [CountryOk], True
        jmp     @2
    @1: mov     [CountryOk], False
    @2:
      end;
    end.

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