There were, it seems:
Some other cases were, rather than promoting to the correct type for the
operands, instead promoting to another type, and then leading to the
incorrect result.
Eg:
unsigned int x, y;
int z;
...
z=x/y;
Where the bug led to doing the '/' operation as 'int' rather than as
'unsigned int', essentially:
z=((int)x)/((int)y);
This had already partly addressed but on another code-path (which broke
with tweaking some other type-system rules, causing it to fall back to a
path which had this bug).
The workaround in this case was to tweak the logic to do, essentially:
unsigned int T; //temporary
T=x/y;
z=(int)T; //needed for correct sign-extension.
The original code-path would do the operation as "unsigned int", but
then the result value would have been zero-extended to 64-bits despite
its type being 'int'.
...
This was mostly an IR level issue (in the RPN -> 3AC conversion stage).
>
> Still haven't resolved the issues I was looking for.
>
>
> There appears to be a case where there is a behavioral difference
> between the CPU core and my emulator, but I have yet to isolate it.
>
> Its main effect is that things can skew/warp weirdly when drawing the
> floor and ceiling in Doom in the Verilog implementation.
>
Some of my other (prior) tweaks appear to have maybe caused this issue
to go away. Still didn't entirely nail it down (the running simulation
is from around the time I fixed a bug with the builtin-memcpy logic, and
worked some on the builtin-memset).
However, some other evidence implies it may have been due to
out-of-range angles (causing accesses to go outside of the sine/cosine
lookup tables), possibly due to one of the previous bugs (previously,
range-masking the angles did partially improve the situation; in that
the floor/cieling textures looked sensible but were not at the correct
orientation).
> There also seems to be an issue where "somewhere or another" things are
> behaving differently on BJX2 than they do on a normal PC, but given this
> is only showing up indirectly (via emergent behaviors), it is being
> rather difficult to nail down.
>
Still ongoing.
After fixing the type-promotion bugs, the behaviors changed here, but
still aren't really "correct".
Though, this is depending on demo playback in ROTT, which has a lot of
"butterfly effect" properties, such as events which happen can influence
the state of the RNG, which changes other things which happen, ...
Similarly, the player's position depends on knockback, which means when
and how the player gets shot/... influences where they end up, and this
is in turn dependent on the positions and behaviors of the enemies,
which are in-turn subject to the RNG (it tries to get repeatable
playback by reseeding the RNG with 0 whenever playing a demo).
Contrast, Doom engine games seem a little more stable here, as the
enemies do not depend on a shared RNG state (so, a slight variation here
or there is less prone to wreck things; and small errors often take a
little longer to build up to point of breaking the demo; though at least
luckily it supplies its own RNG rather than depending on
"rand()"/"srand()" or similar, ...).
The Quake system of just recording where everything was, ..., was
admittedly a lot simpler, but I guess less subject to point out the
existence of minor behavioral issues.
Side note:
Partly as a test, I did add a more Quake-like demo playback system to
ROTT, but this was partly in my (thus far futile) attempt to locate the
initial cause of the divergence (does seem to occur very early on, as
divergences start to pop up pretty much immediately as soon as playback
starts).
Kinda half wondering if mainstream CPUs do something similar for their
POST tests (eg, using butterfly effect to test a bunch of different
instructions); as testing instructions individually gets pretty bulky
(and a POST test probably doesn't need to care which instruction with
which inputs caused the error; only that an error has taken place).