VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've noticed, when running the test386.asm testsuite, that the BCD instructions have some very odd behaviour, comparing to 86box (808x: https://github.com/86Box/86Box/blob/master/src/cpu/808x.c , 286: https://github.com/86Box/86Box/blob/master/sr … u/x86_ops_bcd.h ).

It seems like various oddly mismatched things occur in the real BCD handling (according to getting the testsuite not to fail):
DAA/DAS: Only check for AL>99, never 9F. Carry cleared before and or-ed during the first correction case(borrow or carry during the add/substract). High correction case (>99h) doesn't clear carry flag.
AAA/AAS: really substracting/adding 0x106 on 286, just 6 on 808x (simulated on 286+). 808x adds 1 to AH after this operation. sign/zero/carry/overflow is from 8-bit addition/substraction operation. The resulting AX register is like it's performed the 0x106 addition/substraction instead of what the flags indicate (which seem to report what the AL+/-6 operation did).

Is this odd behaviour somehow correct on 286+ machines? Doesn't that mean that since on 808x no carry from the low byte substracting 6 into the high byte occurs, the result in AX is different on a 808x?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 3, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie

I have hardware-generated, per-opcode CPU tests for the 8088, 80286 and 80386 that can answer these sort of questions.

https://github.com/SingleStepTests/8088
https://github.com/SingleStepTests/80286
https://github.com/SingleStepTests/80386

The 8088/8086 does indeed have different BCD logic than the 286+.
You have been reluctant to attempt to use them so far to date, but I can only reiterate that I made them precisely for purpose of emulator validation.

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 2 of 3, by superfury

User metadata
Rank l33t++
Rank
l33t++

Still, that only tests the results, just like test386.asm does, while not explaining what the behaviour is (how the flags are updated in the ALU). In my current emulation of the 286+:
- Sign, zero, parity flag according to logic 8-bit result in AL.
- Overflow according to 8086-style result if it was 808x-style, using 8-bit addition/substraction.
- AX result like it is in 286+ style, using 16-bit addition/substraction, discarding the flags.

That's all I figured out so far.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 3, by superfury

User metadata
Rank l33t++
Rank
l33t++

So like I actually asked, what is the real behaviour of the 286+ AAA/AAS instructions? And I don't mean what the results of certain operations are, I mean what actually happens during the flag calculations.
Especially the overflow flag, which seems to be the main thing that has to do some weird behaviour on 286, since the 16-bit addition/substraction generates different overflow flag results from 8-bit math (which isn't compatible with the 808x flags if used, test386.asm causes errors if that is done).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io