/*

  This is a part of the Project Frontier's Source code.

  Copyright (C) 1997-98 Francis Gastellu
                    aka Lone Runner/Aegis

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

/*

OS detection routines. Used to know the way to release unused cpu slices

*/

#include "..\com\detect.h"

char In_DV=0, In_VM=0, In_OS2=0;

unsigned int OS2_GetVersion(void)
{
asm {
  MOV    AH, 30h // { Dos Get Version Call }
  INT    21h     // { AL = major version * 10, AH = minor version }
  MOV    BH, AH  // { save minor version }
  xor    AH, AH
  MOV    CL, 10
  div    CL      // { divide by 10 to get the major version }
  MOV    AH, BH  // { restore minor version }
  XCHG   AH, AL  // { AH = major, AL = minor }
  }
}

unsigned int DV_GetVersion(void)
{
asm {
  MOV    CX,'DE'   //  { CX+DX to 'DESQ' (invalid date) }
  MOV    DX,'SQ'
  MOV    AX,02B01H //  { Dos' set date funct. }
  INT    21H       //  { call Dos }
  CMP    AL,0FFH   //  { Was it invalid? }
  JE     No_dv     //  { yep, no dv }
  MOV    AX,BX     //  { AH=major AL=minor }
  MOV    In_DV,1   //  { Set In_DV flag }
  JMP    DvGv_x    //  { other routines }
  }
  No_dv:
  asm xor    AX,AX //  { Return 0 or no DV }
  DvGv_x:
}

void DV_Pause(void)
{
  if (In_DV)
  	{
  	asm {
    	MOV AX, 1000h  // { pause Function }
    	INT 15h
    	}
	}
}

void KillTime(void)
{
  if (In_VM)
  	{
  	asm {
    	MOV AX, 1680h   // { give up VM time slice }
    	INT 2Fh
    	}
  	}
  else
  	if (In_DV)
		{
		asm	{
            MOV AX, 1000h  //  { DV pause call }
            INT 15h
        	}
        }
    else
    	MT_Pause();     // { Dos Idle call }
}

void DV_begin_Critical(void)
{
asm {
  	MOV AX,0101BH      // { DV begin critical Function }
  	INT 15h           //
  	}
}

void DV_end_Critical(void)
{
asm {
	MOV AX,0101CH      // { DV end critical Function }
    INT 15h
    }
}

void MT_Pause(void)
{
asm {
	DB 0cdh
	DB 028h
	}
}

void DV_Sound(int freq, int dur)
{
asm {
  MOV   AX,1019H
  MOV   BX,freq  // { frequency above 20 Hz }
  MOV   CX,dur   // { duration in clock ticks }
  INT   15H
  }
}

void DetectOS(void)
{
  DV_GetVersion(); 	 // { discard answer.  Just update In_DV }
  asm {
    MOV AX, 1680h
    INT 2Fh          // { Gives up time slice in most 386+ virtual machines }
    not AL           // { AL = 00h if supported, remains 80h if not }
    MOV CL, 7
    SHR AL, CL       // { move bit 7 to bit 0 For a Boolean }
    MOV In_VM, AL    // { update the flag }
  	}
  In_OS2 = (OS2_GetVersion() >= 0x0100); // { version 1.0 or greater }
}

