Unit TimeTask;

Interface

{ TaskRec.OS

   0 : No MultiTasking
   1 : MS Windows 3.x
   2 : OS/2
   3 : DESQview
   4 : TopView
   5 : PC-MOS/386
   6 : Linux DOSEMU
   7 : OS/2 Warp
   8 : Win95
   9 : European MS-DOS
  10 : DoubleDOS
}

Type
  TaskRec = Record
    OS      : Word;
    Version : Word; {writeln('Version ',hi(Version), '.', lo(Version) );}
    Delay   : Word;
  End;

Const
  Task    : TaskRec = (
  OS      : 0;
  Version : 0;
  Delay   : 100
  );

Procedure TimeSlice;
Procedure InitMulti;

Implementation

{$IFDEF OS2}
Uses
  Os2Base,
  OpCrt,
  VPutils;
{$ENDIF}

{$IFDEF WIN32}
Uses
  Windows,
  Forms;
{$ENDIF}

Procedure InitMulti;
{$IFDEF MSDOS}
Assembler;
Asm
  mov  Task. OS, 0
  mov  Task. Version, 0

  { Start of OS/2 system detection              }
  mov  AX, 4010h       { int 2fh, AX=4010h      }
  int  2fh
  cmp  AX, 4010h       { AX was changed?        }
  jne  @OS2            { Yeah, it is!           }
  { End of OS/2 detection part                  }

  (*
  {* Start of Win95 detection ***************** }
  push BX ; push DX    { saving registers vals  }
  push DS ; push SI
  mov  AX, 4A33h       { function 4A33h of 2fh  }
  int  2fh
  pop  SI ; pop  DS    { restoring regs         }
  pop  DX ; pop  BX
  cmp  AX, 0           { AX=0 if MS-DOS 7.0     }
  je   @Win95
  {* End of Win95 detection part ************** }
  *)

  {* Starting MS Win 3.x system detection ***** }
  mov  AX, 160Ah       { function 160Ah of 2fh  }
  Int  2Fh
  cmp  AX, 0           { AX=0 if Win 3.1        }
  je   @Windows
  {* End of M$-SUX detection part ************* }

  mov  AX, 1022h
  mov  BX, 0000h
  Int  15h
  cmp  BX, 0
  jne  @DESQview

  mov  AH, 2BH
  mov  AL, 01h
  mov  CX, 4445h
  mov  DX, 5351h
  Int  21h
  cmp  AL, $FF
  jne  @TopView

  mov  AX, 3000h
  mov  BX, 3000h
  mov  CX, 3000h
  mov  DX, 3000h
  int  21h
  cmp  AL, 3
  je   @PC_MOS

  {* Starting European MS-DOS 4.0 detection *** }
  mov  AH, 87h  { int 21h, AH=87h               }
  mov  AL, 0
  int  21h
  cmp  AL, 0    { if AL <> 0 then Eur. detected }
  jne  @European
  {* End of European MS-DOS detection part **** }

  {* DoubleDOS system detection *************** }
  mov  AX, $E400       { int 21h, AX=E400h      }
  int  21h
  cmp  AL, 0           { AL=0 if not installed  }
  jne  @DoubleDOS
  {* DoubleDOS system detection end *********** }

  {* Start Linux DOSEMU detection ************* }
  {* Check for int E6h vector address ********* }
  mov  AH, $35  { get int vector                }
  mov  AL, $E6  { of int E6h                    }
  int  21h

  mov  ES, AX
  cmp  AX, $F000 { int E6h points to F000:0E60? }
  jne  @Fin
  cmp  BX, $0E60
  jne  @Fin

  mov  AX, 0 { It's points to address F000:0E60 }
  int  $E6
  cmp  AH, $AA
  jne  @Fin
  cmp  AL, $55
  je   @Linux
  {* End of Linux DOSEMU detection ************ }

  jmp  @Fin

  @Windows:
  Mov  Task. OS, 1
  Mov  Task. Version, BX
  jmp  @Fin

  @OS2:
  Mov  Task. OS, 2

  cmp  AX, 0000h
  je   @Warp

  Mov  BH, AH
  XOr  AH, AH
  Mov  CL, 10
  Div  CL
  Mov  AH, BH
  Xchg AH, AL
  jmp  @OS2_done

  @Warp:
  mov  AH, 3
  mov  AL, 0
  mov  Task. OS, 7

  @OS2_done:
  Mov  Task. Version, AX
  jmp  @Fin

  @DESQview:
  mov  Task. OS, 3
  mov  Task. Version, BX
  jmp  @Fin

  @TopView:
  mov  Task. OS, 4
  mov  Task. Version, BX
  jmp  @Fin

  @PC_MOS:
  mov  Task. OS, 5
  mov  Task. Version, AX
  jmp  @Fin

  @Linux:
  {Setting HogTreshold to optimal value}
  mov  AH, 12h
  mov  BX, 20
  int  $E6

  {Reporting, what we are running under Linux DOSEMU}
  mov  Task. OS, 6
  mov  Task. Version, BX
  jmp  @Fin

  @Win95:
  mov  AX, 160Ah       { function 160Ah of 2fh  }
  Int  2Fh
  mov  Task. OS, 8
  mov  Task. Version, BX
  jmp  @Fin

  @European:
  mov  Task. OS, 9
  mov  Task. Version, 0400
  jmp  @Fin

  @DoubleDOS:
  mov  Task. OS, 10
  mov  Task. Version, 0100
  jmp  @Fin

  @Fin:
{$ENDIF}
{$IFDEF OS2}
Begin
  If VPutils. Os2Version = 7700 Then
    Task. OS := 7
  Else
    Task. OS := 2;

{$ENDIF}

{$IFDEF WIN32}
Begin
  Task. OS := 8;
{$ENDIF}
End;

Procedure TimeSlice;
{$IFDEF MSDOS}
Assembler;
Asm
  cmp  Task. OS, 0
  je   @Fin
  cmp  Task. OS, 1
  je   @Win
  cmp  Task. OS, 2
  je   @OS2
  cmp  Task. OS, 3
  je   @DV_TV
  cmp  Task. OS, 4
  je   @DV_TV
  cmp  Task. OS, 5
  je   @PC_MOS
  cmp  Task. OS, 6
  je   @Linux
  cmp  Task. OS, 7
  je   @OS2
  cmp  Task. OS, 8
  je   @Win95
  cmp  Task. OS, 9
  je   @European
  cmp  Task. OS, 10
  je   @DoubleDOS

  @DV_TV:
  mov  AX, 1000h
  Int  15h
  jmp  @Fin

  @Win:
  mov  AX, 1680h
  Int  2Fh
  jmp  @Fin

  @OS2:
  mov  ax,35
  mov  dx,0
  hlt
  db   35h, 0CAh
  jmp  @Fin

  @PC_MOS:
  int  28h
  jmp  @Fin

  @Linux:
  int  28h
  jmp  @Fin

  @Win95:
  mov  AX, 1680h
  Int  2Fh
  jmp  @Fin

  @European:
  mov  AH, 89h
  mov  CX, 55     {  default time quant (55mS)  }
  Int  2Fh
  jmp  @Fin

  @DoubleDOS:
  mov  AX, $EE01
  Int  21h
  jmp  @Fin

  @Fin:
{$ENDIF}

{$IFDEF OS2}
Begin
  DosSleep (55);
{$ENDIF}

{$IFDEF WIN32}
Begin
  Application. ProcessMessages;
{$ENDIF}

End;

End.
