UNIT Slice;

{$I platform.inc}

{ deze unit is gemaakt uit de PD "slice" code die verschillende }
{ multitaskers kan detecteren en time slices vrij kan geven.    }

INTERFACE

PROCEDURE Slice_Detect;          { OS2: no call means don't call DosSleep! }
FUNCTION  Slice_GetMultiTaskerName : STRING;
PROCEDURE Slice_Now;


IMPLEMENTATION

USES
{$IFDEF PLATFORM_OS2}
{$IFNDEF FPC}
    OS2Base,
{$ELSE}
    DosCalls,
{$ENDIF}
{$ENDIF}
    Ramon;

{$IFDEF PLATFORM_DOS_ALL}
TYPE MultiTaskersType = (mtNone,mtDesqview,mtWin3x,mtOS2_20,mtOS2_21plus);

VAR FoundMTName : STRING[40];
    FoundMT     : MultiTaskersType;
{$ENDIF}

{---------------------------------------------------------------------------}
{ Slice_Detect                                                              }
{                                                                           }
{ Deze routine detecteert de aanwezige multi-tasker en enabled time slicing }
{ voor hiervoor.                                                            }
{                                                                           }
PROCEDURE Slice_Detect;

VAR FoundDV : BOOLEAN;
    VerMaj  : BYTE;
    VerMin  : BYTE;

BEGIN
{$IFDEF PLATFORM_DOS_ALL}
     { see if Windows 3.x in Enhanced Mode is around }
     VerMaj:=0;

     ASM
        mov ax,$1600
        int $2F

        cmp al,0
        jz @no_Windows

        cmp al,$80
        jz @no_Windows

        cmp al,1           { Windows/386 2.x; not supported }
        jz @no_windows

        cmp al,$FF         { Windows/386 2.x; not supported }
        jz @no_windows

        { If AL is none of the above values,     }
        { it is the Windows major version number }

        mov VerMaj,al
@no_windows:
     END;

     IF (VerMaj >= 3) THEN
     BEGIN
          FoundMT:=mtWin3x;
          FoundMTName:='Windows '+Byte2String (VerMaj)+'.x';
          Exit;
     END;

     { see if it is OS/2 2.0 }
     { dos versie major 20, minor <10 is expected }
     ASM
        mov ah,$30    { DOS get version fn. }
        int $21

        mov VerMaj,al
        mov VerMin,ah
     END;

     IF (VerMaj >= 20) AND (VerMin < 10) THEN
     BEGIN
          FoundMT:=mtOS2_20;
          FoundMTName:='OS/2 2.0';
          Exit;
     END;

     { check for OS/2 2.1 or later }

     IF (VerMaj >= 20) AND (VerMin >= 10) THEN
     BEGIN
          FoundMT:=mtOS2_21plus;
          FoundMTName:='OS/2 2.1 or later';
          Exit;
     END;

     { kijk of desqview in de buurt is }
     ASM
        mov cx,'DE'
        mov dx,'SQ'
        mov ax,$2B01       { DOS set date function }
        int $21
        { als AL nu FF is, dan is desqview niet in de buurt }
        inc al              { wordt FALSE als desqview er NIET is }
        mov FoundDV,al
        mov VerMaj,bh
        mov VerMin,bl
     END;

     IF FoundDV THEN
     BEGIN
          FoundMTName:='DesqView '+Byte2String (VerMaj)+'.'+Byte2String (VerMin);
          FoundMT:=mtDesqView;
          Exit;
     END;
{$ENDIF}
END;


{---------------------------------------------------------------------------}
{ Slice_GetMultiTaskerName                                                  }
{                                                                           }
{ Deze routine geeft de naam van de gevonden multi-tasker terug.            }
{                                                                           }
FUNCTION Slice_GetMultiTaskerName : STRING;
BEGIN
     Slice_GetMultiTaskerName:='';

     {$IFDEF PLATFORM_DOS_ALL}
     Slice_GetMultiTaskerName:=FoundMTName;
     {$ENDIF}
END;


{---------------------------------------------------------------------------}
{ Slice_Now                                                                 }
{                                                                           }
{ Roep zo vaak mogelijk aan om time slices weg te geven.                    }
{                                                                           }
PROCEDURE Slice_Now;
BEGIN
     {$IFDEF PLATFORM_OS2}
     DosSleep (0);
     {$ENDIF}

     {$IFDEF PLATFORM_WIN32}
     {## add Win32 time slicing support}
     {$ENDIF}

     {$IFDEF PLATFORM_DOS_ALL}
     CASE FoundMT OF
          mtNone :
              Exit;

          mtDesqView :
              ASM
                 mov ax,$101A   { switch to DV's stack }
                 int $15
                 mov ax,$1000   { give up time-slice }
                 int $15
                 mov ax,$1025   { restore local stack }
                 int $15
              END;

          mtWin3x,
          mtOS2_20 :
              ASM
                 mov ax,$1680       { Win 3.x / OS/2 2.x timeslice call }
                 int $2F
              END;

          mtOS2_21plus :
              ASM
                 { DX:AX is milliseconds to give up }
                 push bp       { RWI 970114: BP is now saved }
                 xor dx,dx
                 mov ax,1
                 sti
                 hlt
                 db $35,$CA    { Signature to specify DosSleep to OS/2 }
                 pop bp
              END;
     END; { case }
     {$ENDIF}
END;


{---------------------------------------------------------------------------}
{ unit initialization                                                       }
{                                                                           }
BEGIN
     { detecteer een mogelijk aanwezige multitasker en zet daarma }
     { FoundMT en FoundMTName.                                    }
     {$IFDEF PLATFORM_DOS_ALL}
     FoundMT:=mtNone;
     FoundMTName:='';
     {$ENDIF}

     {Slice_Detect; manual for the moment, so it can be disabled...}
END.
