computer's BIOS date

how can i retrieve the computer's BIOS date with Delphi Pascal (16 bits version)?

I tried memory location Mem[$FFFF:$0005] but this gives a general protection error.

I made a DOS-program in Turbo Pascal 4.0 about 6 year's ago which retrieves 8 bytes starting at memory location $FFFF:$0005. This 8 bytes contain the BIOS date of the computer. The program worked well with the three generations of computers i owned (286, 486 Pentium 166).

But in Delphi i get a general protection failure at run time in the line marked with {*} in the function below.

function
  BiosDate: string;
var
  Offset: Word;
begin
  Result := '';
  for Offset := $0005 to $000C do
    Result := Result + Char(Byte(Ptr($FFFF, Offset)^));  {*}
end;
rjAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

peter_vcCommented:
I think I have an easy solution, but I need to know if $FFFF:$0005 is really the correct location.  The Undocumented PC and Undocumented DOS don't seem to have that info.


0
rjAuthor Commented:
Edited text of question
0
rjAuthor Commented:
i expanded my question about biosdate with some more info.
0
PMI ACP® Project Management

Prepare for the PMI Agile Certified Practitioner (PMI-ACP)® exam, which formally recognizes your knowledge of agile principles and your skill with agile techniques.

peter_vcCommented:
Sorry this isn't as clean as it could be, but it works.

Be aware that you may have to call FreeSelector to deallocate the selector created with AllocSelector.

var
  d : Byte;
  dp : ^Byte;
  c : LongInt;
  I : integer;
  date : array[0..7] of char;
begin

c := 1048565;  { $ffff:$0005 }
dp := CreateFarPointer(c,8);
for I:= 0 to 7 do
begin
     d := Byte(dp^);
     Inc(dp);
     date[I] := Chr(d);
end;
end;


function CreateFarPointer(phys:LongInt; length:Cardinal) : Pointer;
var
   limit : Cardinal;
   sel : Cardinal;
begin
    limit := length - 1;

    asm MOV sel,DS end;

    sel := AllocSelector(sel);
    SetSelectorBase(sel, phys);
    SetSelectorLimit(sel, limit);
    Result:=Ptr(sel,0);

end;

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rjAuthor Commented:
Thanks for your answer. You're a real expert.
I added your source to my project and it worked!

I have just one question: what is the meaning of the assembler line in your source (asm MOV sel,DS end;)? I tried to run without this line and this gave also the same result.

bye, robbert-jan

0
peter_vcCommented:
It stores the data segment register into the variable sel.  It just ensures that its using the proper parameters to allocate the selector.  You should leave it in.

As you are testing it, put a call to it in a loop a few thousand times and let me know what happens.  I'm wondering if a call to FreeSelector is needed.  I think you'll need to free it once your done with the pointer.  I really should have done this, but ...

Credit for this actually goes to Andrew Shulman, author of Undocumented Windows and many other titles.



0
rjAuthor Commented:
Hi,
I rewrited your code according to my programming standards. (see below). I tested the code with and without the FreeSelector command, calling the routine 30000 times. Without FreeSelector the program is crashing leaving Windows in an instable state. With the FreeSelector command there is no problem. So I think your advise on using FreeSelector is a right one.

I have rated your solution as excellent! I also had dropped my question in the Pascal topic area, sou you can get another 200 pionts by locking this question in that area.

If you have more comments, please contact me at RJM@XS4ALL.NL

(* begin of code *)

uses
  WinProcs;

function
  fBiosDate: string;
{this routine returns the BIOS-date of the computer}
var
  Selector: Word;
  CharacterIndex: Integer;
begin
  Result := '';

  asm {this assembler code ensures a proper allocation of the Selector}
    MOV Selector, DS;
  end;

  Selector := AllocSelector(Selector);
  try
    SetSelectorBase(Selector, 16*$FFFF + $0005);
    SetSelectorLimit(Selector, 8 - 1);

    for CharacterIndex := 0 to 7 do
      Result := Result + Chr(Byte(Ptr(Selector, CharacterIndex)^));
  finally
    FreeSelector(Selector);
  end;
end;

(* end of code *)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.