I guess the question is are dates crucial? Losing hardware acceleration might be a real pain in the ass.

Anyhow, I've been tinkering, and I've made some interesting discoveries. I created local copies of some of the crucial routines. The majority of them appear to work correctly. The problem appears to be in converting TDateTime to TTimeStamp.

So... with much tinkering, I have a possible solution...

Basically, I've created versions of the key routines that only work on Integers and it appears to work (even when pushing in float date using trunc() that would break the standard routines).

[pascal]
function intDateTimeToTimestamp(DateTime:integer):TTimestam p;
var
temp : cardinal;
begin
temp:=dateTime*86400;
result.date:=DateDelta+(temp div 86400);
result.time:=temp-result.date;
end;

procedure LocalDivMod(Dividend: Integer; Divisor: Word;
var Result, Remainder: Word);
asm
PUSH EBX
MOV EBX,EDX
MOV EDX,EAX
SHR EDX,16
DIV BX
MOV EBX,Remainder
MOV [ECX],AX
MOV [EBX],DX
POP EBX
end;

function LocalIsLeapYear(Year: Word): Boolean;
begin
Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
end;

const
LocalMonthDays: array [Boolean] of TDayTable =
((31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));

procedure intDecodeDate(Date: Integer; var Year, Month, Day, DOW: Word);
const
D1 = 365;
D4 = D1 * 4 + 1;
D100 = D4 * 25 - 1;
D400 = D100 * 4 + 1;
var
Y, M, D, I: Word;
T: Integer;
DayTable: PDayTable;
begin
T := IntDateTimeToTimestamp(date).date;
if T <0>= D400 do
begin
Dec(T, D400);
Inc(Y, 400);
end;
LocalDivMod(T, D100, I, D);
if I = 4 then
begin
Dec(I);
Inc(D, D100);
end;
Inc(Y, I * 100);
LocalDivMod(D, D4, I, D);
Inc(Y, I * 4);
LocalDivMod(D, D1, I, D);
if I = 4 then
begin
Dec(I);
Inc(D, D1);
end;
Inc(Y, I);
DayTable := @LocalMonthDays[LocalIsLeapYear(Y)];
M := 1;
while True do
begin
I := DayTable^[M];
if D < I then Break;
Dec(D, I);
Inc(M);
end;
Year := Y;
Month := M;
Day := D + 1;
end;
end;
[/pascal]

The only real requirements for this are that if you are using TDateTime values, you pass them into the routine using trunc(datetime).

I can't guarantee that this is going to work with every date because the original DateTimeToTimestamp routine is written in assembler and my x86 is VERY poor, so whilst it works (using my test data) it may not be correct for other dates. There is some kind of conditional negation I think in the routine... I don't have that, so certain date ranges could go bang.

But, these routine do appear to work in my test bed.

I think the reason is because (from what I can tell) once you call the intDecodeDate routine, there are no floating point instructions such as FMul which are present in the orginal versions.

I'm guessing from this that somewhere along the lines, unDelphiX or DirectX changes some flags or settings in the FPU that breaks standard routines.

Anyhow.... hope this helps.

As a side note... if someone in the know could possibly explain why this problem is occuring, I'm sure seiferalmasy would appreciate it, because I know I would :-)