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 19, 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 19, 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 19, 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 19, 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 19, 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.

Reply 11 of 19, by Keatah

User metadata
Rank Member
Rank
Member

Read through this thread.. Some of which I understand, some of it I don't. Not a developer. But instead a technical hobbyist.

Can someone explain why the Intel 387 diagnostics fails the Trancendentals test on DosBox (any x86 version) including latest DosBox-X?

https://archive.org/details/intel387dxmathcop … ities_304833001

runmcp_000.png
Filename
runmcp_000.png
File size
7.61 KiB
Views
2828 views
File license
Public domain
runmcp_001.png
Filename
runmcp_001.png
File size
10.18 KiB
Views
2828 views
File license
Public domain
runmcp_002.png
Filename
runmcp_002.png
File size
9.87 KiB
Views
2828 views
File license
Public domain

Reply 12 of 19, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

The diagnostic program executes opcode 0xDB 0xE1, which according to docs is FNDISI (no-wait disable interrupts) and only meaningful on the original 8087; 287 and later treat it as no-operation. However, the program is expecting bit 7 of the FPU Control Word to be set after executing the instruction, and the transcendental test passes when I force that result with the debugger. Bit 7 is documented as "reserved", so there appears to be undocumented behavior involved.

Edit: bit 7 of the Control Word is "interrupt mask" on the 8087, and FNDISI probably should change the bit on that FPU. This suggests: A) the program is misidentifying the coprocessor as an 8087 and testing it as such (unlikely because it notes that an i486 family coprocessor was found), B) the program has a bug, C) FNENI and FNDISI toggle bit 7 of the Control Word on later coprocessors, even if the bit is otherwise meaningless.

Last edited by ripsaw8080 on 2021-11-09, 17:47. Edited 1 time in total.

Reply 15 of 19, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

The interrupt mask test is apparently supposed to fail, as it causes a different set of tests to run. DOSBox passes all 8087 tests, but there is apparently an issue with at least one of the non-8087 tests.

The first failing test is FINIT, FLDLG2, F2XM1 three times, FLDT to load an 80-bit constant, then FUCOMPP to compare the result to the constant and expecting them to be equal. Possibly something with precision, but will need some analysis to identify the specific issue.

Reply 16 of 19, by hail-to-the-ryzen

User metadata
Rank Member
Rank
Member

A later version of MCPDIAG at this (not secure) web site:
http://annex.retroarchive.org/cdrom/pier-01/017A/index.html

It runs on 32-bit Windows and fails on my host system at the same transcendental test. It is an Intel Core2Duo. It also has another set of tests, but they do not seem useful for the above issue.

Reply 17 of 19, by hail-to-the-ryzen

User metadata
Rank Member
Rank
Member

In the transcendental test, a 1993 version of MCPDIAG seems to make comparisons between values of PI under two different rounding modes. It loads a log value first from the fpu and then loads these values of PI for the comparison. The fpu status word is compared to a value in memory.

The program has a help screen on the transcdentals, but it does not appear to correspond to the code generated and shown in the debugger window. It is possible the program is running tests that do not correspond to the pass/fail reports on-screen.

There is more about estimation of fpu values, such as PI, here:
randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion

Reply 18 of 19, by keropi

User metadata
Rank l33t++
Rank
l33t++

transcendental test also fails with a p1 233mmx cpu
IMHO this is a non-issue for DOSBox

🎵 🎧 PCMIDI MPU , OrpheusII , Action Rewind , Megacard and 🎶GoldLib soundcard website

Reply 19 of 19, by xor2003

User metadata
Rank Newbie
Rank
Newbie

Instructions tests from qemu.
x86 instructions test (testi386.exe) is build using mingw right now.
The HX extender is used so you can run in on real windows system and inside Dosbox and compare results under emulator.

Attachments