VOGONS


First post, by tnmlyger

User metadata
Rank Newbie
Rank
Newbie

I've encountered a really strange malfunction of an old PowerBASIC/DOS program and was able to trace it down to this:

q1&&=&h1234567890abcdee
print (q1&& mod 7)

I'm initializing a quad integer variable (64-bit) and want the program to output its value mod 7. The correct result is 3, and this is done correctly in native 32-bit Windows pre-8 as well as in the Windows version of DOSBOX.

Moving the same binary to either x86/x64 Linux versions or the Raspberry Pi ARM version consistently yields the result 0. The behavior is consistent across the last few DOSBOX releases, too.

It works fine if the number uses the lowest 56 bits but as soon as you use bits 57-63 (not using bit 64 due to using positive numbers only), it peters out.

I realize this may be a complete outlier of a problem but I wanted to ask if anybody here has had similar issues with larger data types.

Thanks in advance for any advice re: known issues.

Reply 1 of 10, by hail-to-the-ryzen

User metadata
Rank Member
Rank
Member

This thread explains the general issue of fpu emulation in dosbox:
https://github.com/joncampbell123/dosbox-x/issues/119

...core attempts to use the host floating point support to emulate Intel x87 instructions, but it does so by typecasting everything to "double", even 80-bit extended formats.

The Raspberry Pi has the above issue with any of its dosbox fpu cores since it only supports up to the 64-bit values. That is one possible cause, but it should be diagnosed by testing. DOSBox-X has extended the fpu emulation in some cases.

Another possible cause is use of the dynrec core instead of the dynamic core for the x86/x64 case. The dynrec core has other limitations in its fpu emulation. May test by verifying use of dynamic core in x86/x64 Linux.

Reply 2 of 10, by tnmlyger

User metadata
Rank Newbie
Rank
Newbie

Thank you very much for this! After having followed the thread and jump-off points from the thread, it seems like trying to make this work is futile given the mantissa simply doesn't have enough bits to store a 64-bit value without loss of data. And loss of data means that the CRC will fail in my use case, as will encryption and decryption.

Appreciate the heads-up!

Reply 4 of 10, by tnmlyger

User metadata
Rank Newbie
Rank
Newbie

Thank you, jmarsh.

In PB, quad integers are stored in eight consecutive bytes and follow the little endian format. They aren't stored as floating point values.

Perhaps I misunderstood what you wrote, though.

Reply 6 of 10, by tnmlyger

User metadata
Rank Newbie
Rank
Newbie

Which is exactly my point.

DOSBOX/Windows returns the exact same results as the native code does on a compatible version of Windows.

DOSBOX/Linux (I've run it on Ubuntu, Fedora, SuSe and a few others) returns the wrong result, as does DOSBOX/Raspbian.

DOSBOX/Windows is able to use the full 64 bit of a quad integer.

DOSBOX/Linux and DOSBOX/Raspbian work fine as long as quad ints only use the least significant 56 bits. So this looks to me like those cores might be mapping quad int to a floating point number using a seven-byte mantissa with an eighth byte for the exponent.

Your reaction shows me that I'm not the only one puzzled by this. I'll contact the crew.

Thank you again!

Reply 9 of 10, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie

It uses FILD to load 7 and 0x1234567890abcdee into floating point registers then performs FPREM to find the remainder (mod). Those are FPU instructions, not integer.

Last edited by jmarsh on 2020-07-06, 09:18. Edited 2 times in total.