{***********************************************************************}
{									}
{ __InitSup   Detection of machine type and keyboard configuration	}
{									}
{ procedure __InitSup							}
{									}
{ Description This procedure detects the IBM model identification, sets }
{	      processor and machine type, detects the keyboard con-	}
{	      figuration and initializes the unit exported variables.	}
{	      It is an internal routine, called only by the Unit_Sup	}
{	      initialization code.					}
{									}
{ Version     4.01 (C)Copyright Blaise Computing Inc.  1988		}
{_______________________________________________________________________}

procedure __InitSup;

  type
    ROMTable   = record 	       { Information area stored in	}
		   ByteCount : word;   { BIOS ROM later series machines.}
		   ModelByte : byte;
		   SubModel  : byte;
		 end;

  var
    Reg        : registers;
    ROMPtr     : ^ROMTable;
    I	       : integer;
    KbdBuffer  : _KeyBoard absolute _BIOSSEG:$001A;
    SaveBuffer : _KeyBoard;

  begin {__InitSup}

    { First return address to version and copyright information.	}

    _VerCtrlAddr := __RVerSup;

    _PCModel	 := _Ident;	       { Machine identification set.	}

    { If the _PCModel is less than _AT, then a submodel type can be	}
    { returned as well.  For the other models, the submodel type is	}
    { set to zero.							}

    _PCSubModel := 0;
    if (_PCModel < _PS2_M80) then	{ Invalid ident--unknown clone? }
       begin
	 _PCProcessor := _8088;
	 _PCMachine   := _mUnknown
       end
    else
       begin
	 if (_PCModel <= _AT) then
	    with Reg do
	      begin
		AH := $C0;		    { Return the pointer to the }
		Intr(_BSERVICE,Reg);	    { system parameter pointer. }
		ROMPtr	    := Ptr(ES,BX);
		_PCSubModel := ROMPtr^.Submodel
	      end;

	 { Now using the model and submodel bytes, determine the	}
	 { processor type and the actual machine type.			}

	 case _PCModel of
	   _PS2_M80 : begin
			_PCProcessor := _80386;
			_PCMachine   := _mPS2_80
		      end;
	       _CVT : begin
			_PCProcessor := _80C88;
			_PCMachine   := _mCVT
		      end;
	   _PS2_M30 : begin
			_PCProcessor := _8086;
			case _PCSubModel of
			  0 : _PCMachine := _mPS2_30;
			  1 : _PCMachine := _mPS2_25
			end
		      end;
	       _XT2 : begin
			_PCProcessor := _8088;
			_PCMachine   := _mXT2
		      end;
		_AT : begin
			_PCProcessor := _80286;
			case _PCSubModel of
			  0 : _PCMachine := _mAT;
			  1 : _PCMachine := _mAT3x9;
			  2 : _PCMachine := _mXT286;
			  4 : _PCMachine := _mPS2_50;
			  5 : _PCMachine := _mPS2_60;
			  else
			      _PCMachine := _mAT;
			end; {case _PCSubModel}
		      end
		 else
		      begin
			_PCProcessor := _8088;
			_PCMachine   := _PCMachType(_PC - _PCModel + 1)
		      end;
	 end {case _PCModel}
       end;

    { Now return system information.  The DOS major and minor version	}
    { numbers and segment address of the environment table are found,	}
    { and the global variables set.					}

    with Reg do
      begin
	AH := $30;		       { Return the DOS version number. }
	Intr(_DOS,Reg); 	       { The major version number is	}
	_DOSMajorVer := AL;	       { returned in AL and the minor	}
	_DOSMinorVer := AH;	       { version is in AH.		}
      end;
    _EnvSeg := MemW[PrefixSeg:$2C];    { The environment segment is at	}
				       { offset 2C within the PSP.	}

    { In this section, the keyboard and BIOS services presence are	}
    { detected.  First check for the Extended Keyboard BIOS services.	}
    { The Extended Keyboard services are checked by attempting an	}
    { Extended Service function (stuff the keyboard), and then reading	}
    { the keyboard buffer.  This procedure is documented in the IBM	}
    { BIOS Interface manual.  If the Extended Keyboard services are	}
    { available, we can check a BIOS data location to see if the	}
    { Enhanced Keyboard is attached.					}

    _ExtendedKbdBIOS := FALSE;
    _EnhancedKbd     := FALSE;

    { Save the existing keyboard buffer and head and tail pointer	}

    SaveBuffer := KbdBuffer;

    { Disable interrupts to forestall more keystrokes.			}

    Inline($FA);		       { $FA = CLI			}

    { Check for Extended Keyboard services				}

    with Reg do
      begin			{ See if we can stuff the keyboard buf- }
	AH := $05;		{ fer using the Extended BIOS function. }
	CX := $FFFF;
	Intr(_KEYBD,Reg);
	Inline($FA);		{ CLI again. BIOS turns on interrupts	}
	if (AL = $00) then	{ Function is supported 		}
	  repeat
	    AH := $10;		{ Extended keyboard read function.	}
	    Intr(_KEYBD,Reg);
	    Inline($FA);	{ CLI again, turned on by BIOS		}
	    Inc(I);
	    _ExtendedKbdBIOS := (AX = $FFFF)
	  until ((I > 15) or (_ExtendedKbdBIOS));

	{  If we find the Extended BIOS, check for Enhanced Keyboard.	}
	{  The boot routine sets a flag in the BIOS data area.		}

	if (_ExtendedKbdBIOS) then
	   if (Mem[_BIOSSEG:$0096] and $0010) <> 0 then { Mask bit 4	}
	       _EnhancedKbd := TRUE;

      end;

    { Now restore original keyboard buffer so no key strokes are lost,	}
    { then enable interrupts.						}

    KbdBuffer := SaveBuffer;
    Inline($FB) 		       { $FB = STI			}

  end;	{__InitSup}
