Box86 - Linux Userspace x86 Emulator


So will it not be possible to use Wine with this?
Wine is still not in the scope of Box86. While it might work, in its current state, the Dynarec will probably not be used because the "exe" code is not part of any elf code and the interpretor will be used. It's a crude mecanism to avoid using dynarec on Self Modifying code or Code emitted by the program. This may change on the future, but for now,I don't want to develop anything to detect changed code before before executions...

Great work!
Thanks :) !
 
Don't worry, it's not a feature request. (Not yet, anyway! :3)

So it doesn't run any self-modifying code? Isn't that common?
 
So it doesn't run any self-modifying code? Isn't that common?
It does run SMC, but not with current Dynarec. I can think of potential workarounds to make it work, but on Linux, it's not that common. Even on Windows, it's mainly used by Packers (like UPX) or protection/DRM... (yes, I'm aware UPX exist on linux, but it's not wildely used, and can be unpacked anyway)
 
That's really impressive! Let me know if you need someone to test stuff, I thinks I still have my (hopefully) low-specs linux games from my last tests.
 
That's really impressive! Let me know if you need someone to test stuff, I thinks I still have my (hopefully) low-specs linux games from my last tests.
You can start some testing already, most things should be working and with some reasonnable speedup already. There are still room for optimizations (like, I need to optimize cmp32/cmp8 at least, thta will benefit all games, but I've noticed that espacially RetroCityRampageDX seems a good testing candidate for this), and SSE/SSE2 (and MMX) is done yet, so every games using this technologie will not get as much boost as it can.

If you find a game that crash (if possible at the beggining), but run fine without dynarec (use BOX86_DYNAREC=0 to disable dynarec at command line), I am greatly interrested.
 
I didn't think Wine needed self modifying code to work. I thought it worked basically as a lib shim i.e. it plugs into the existing api and reimplements the bits of windows you don't have. Although it would effectively need to relink the binary to insert its shim, which might count as self-modifying code at least during the load phase. I wouldn't know, I uninstalled wine many years ago now on my own systems.
 
Last edited:
Here is a story of a bug:

I try as much games or program as I can to test the behavior of Box86 and now Box86 Dynarec.One of the program I tried was custom build of PrBoom. It's of course open source, so running an x86 version has no real value, except for debugging. And with the dynarec, while the game is now basically fullspeed (using software renderer in 640x480) exept with the meltdown transition effect (I guess it's unimplemented opcode in the dynarec, but I haven't checked yet), I noticed some graphic artifact in the looping demo. I started a game (Doom II), go back to grab the chainsaw, and sure enough, some walls were missing. I saved the game in a correct position, and tried again with Dynarec off, and yeah, interpreted version worked.

prboomissue.png

Having the source at hand helps a lot here. So using the basic technics of "printf stuff and compare to a reference", I tried to isolate a part of the init data where data diverge (between interpreted and dynarec). I thought this was linker to some of the Integer Math trick Doom use, so I started with "angle_t" math to go up to load of the BSP nodes to finish to a simple function "R_CheckBBox" (well, that took me something like 3H).
This function looks like this:
Code:
static boolean R_CheckBBox(const fixed_t *bspcoord)
{
  angle_t angle1, angle2;
  {
    int        boxpos;
    const int* check;
    // Find the corners of the box
    // that define the edges from current viewpoint.
    boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT ] ? 1 : 2) +
      (viewy >= bspcoord[BOXTOP ] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8);
    if (boxpos == 5)
      return true;
    check = checkcoord[boxpos];
    angle1 = R_PointToAngle (bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
    angle2 = R_PointToAngle (bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
  }
  // cph - replaced old code, which was unclear and badly commented
  // Much more efficient code now
  if ((signed)angle1 < (signed)angle2) { /* it's "behind" us */
    /* Either angle1 or angle2 is behind us, so it doesn't matter if we
     * change it to the corect sign
     */
    if ((angle1 >= ANG180) && (angle1 < ANG270))
      angle1 = INT_MAX; /* which is ANG180-1 */
    else
      angle2 = INT_MIN;
  }
  if ((signed)angle2 >= (signed)clipangle) return false; // Both off left edge
  if ((signed)angle1 <= -(signed)clipangle) return false; // Both off right edge
  if ((signed)angle1 >= (signed)clipangle) angle1 = clipangle; // Clip at left edge
  if ((signed)angle2 <= -(signed)clipangle) angle2 = 0-clipangle; // Clip at right edge
  // Find the first clippost
  //  that touches the source post
  //  (adjacent pixels are touching).
  angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
  angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
  {
    int sx1 = viewangletox[angle1];
    int sx2 = viewangletox[angle2];
    //    const cliprange_t *start;
    // Does not cross a pixel.
    if (sx1 == sx2)
      return false;
    if (!memchr(solidcol+sx1, 0, sx2-sx1)) return false;
    // All columns it covers are already solidly covered
  }
And I saw some divergense when in the part "one is behind us"

So now was the time to dissamble and trace what was doing Box86
The interresting part x86 asm looked like this
Code:
angle1=9397e6a0, angle2=67915800, clipangle=20080000
EAX=00000035 ECX=000031bf EDX=4047f7ec EBX=4041ccb8 FLAGS=-C---S
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=40395151 39 FE cmp esi, edi
EAX=00000035 ECX=000031bf EDX=4047f7ec EBX=4041ccb8 FLAGS=O-P---
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=40395153 89 FA mov edx, edi
EAX=00000035 ECX=000031bf EDX=67915800 EBX=4041ccb8 FLAGS=O-P---
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=40395155 0F 8C CD 00 00 00 jl 0x40395228
EAX=00000035 ECX=000031bf EDX=67915800 EBX=4041ccb8 FLAGS=O-P---
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=40395228 8D 83 90 75 FE FF lea eax, [ebx-0x18A70]
EAX=40404248 ECX=000031bf EDX=67915800 EBX=4041ccb8 FLAGS=O-P---
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=4039522e 89 04 24 mov [esp], eax
EAX=40404248 ECX=000031bf EDX=67915800 EBX=4041ccb8 FLAGS=O-P---
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=40395231 E8 BA 14 FC FF call 0x403566F0
1 angle behind
EAX=0000000f ECX=000031bf EDX=67915800 EBX=4041ccb8 FLAGS=O-P---
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=40395236 8D 86 00 00 00 80 lea eax, [esi-0x80000000]
EAX=1397e6a0 ECX=000031bf EDX=67915800 EBX=4041ccb8 FLAGS=O-P---
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=4039523c BA FF FF FF 7F mov edx, 0x7FFFFFFF
EAX=1397e6a0 ECX=000031bf EDX=7fffffff EBX=4041ccb8 FLAGS=O-P---
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=40395241 3D FF FF FF 3F cmp eax, 0x3FFFFFFF
EAX=1397e6a0 ECX=000031bf EDX=7fffffff EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=40395246 B9 00 00 00 80 mov ecx, 0x80000000
EAX=1397e6a0 ECX=80000000 EDX=7fffffff EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=9397e6a0 EDI=67915800 EIP=4039524b 0F 46 F2 cmovbe esi, edx
EAX=1397e6a0 ECX=80000000 EDX=7fffffff EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=4039524e 89 CA mov edx, ecx
EAX=1397e6a0 ECX=80000000 EDX=80000000 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=40395250 0F 46 D7 cmovbe edx, edi
EAX=1397e6a0 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=40395253 89 D7 mov edi, edx
EAX=1397e6a0 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=40395255 E9 01 FF FF FF jmp 0x4039515B
EAX=1397e6a0 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=4039515b 8B 45 00 mov eax, [ebp]
EAX=20080000 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=4039515e 89 7C 24 0C mov [esp+0x0C], edi
EAX=20080000 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=40395162 89 74 24 08 mov [esp+0x08], esi
EAX=20080000 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=40395166 C7 04 24 01 00 00 00 mov dword ptr [esp], 0x01
EAX=20080000 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=4039516d 89 44 24 10 mov [esp+0x10], eax
EAX=20080000 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=40395171 8B 44 24 28 mov eax, [esp+0x28]
EAX=404042d8 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=40395175 89 54 24 2C mov [esp+0x2C], edx
EAX=404042d8 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=40395179 89 44 24 04 mov [esp+0x04], eax
EAX=404042d8 ECX=80000000 EDX=67915800 EBX=4041ccb8 FLAGS=-C-A-S
ESP=405a7750 EBP=4047d764 ESI=7fffffff EDI=67915800 EIP=4039517d E8 BE 18 FC FF call 0x40356A40
angle1=7fffffff, angle2=67915800, clipangle=20080000
This is a box86 trace, running with interpretor, and with some added printf to better see where I am.
And now compare with a version with dynarec
Code:
angle1=9397e6a0, angle2=67915800, clipangle=20080000
Running DynaRec Block @0x4038e151 (0x415f8600) emu=0xa8179390
EAX=00000035 ECX=000031bf EDX=404787ec EBX=40415cb8 FLAGS=-C---S
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e151 39 FE cmp esi, edi
EAX=00000035 ECX=000031bf EDX=404787ec EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e153 89 FA mov edx, edi
EAX=00000035 ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e155 0F 8C CD 00 00 00 jl 0x4038E228
EAX=00000035 ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e228 8D 83 90 75 FE FF lea eax, [ebx-0x18A70]
EAX=403fd248 ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e22e 89 04 24 mov [esp], eax
EAX=403fd248 ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e231 E8 BA 14 FC FF call 0x4034F6F0
1 angle behind
EAX=0000000f ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e236 8D 86 00 00 00 80 lea eax, [esi-0x80000000]
EAX=9397e6a0 ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e23c BA FF FF FF 7F mov edx, 0x7FFFFFFF
EAX=9397e6a0 ECX=000031bf EDX=7fffffff EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e241 3D FF FF FF 3F cmp eax, 0x3FFFFFFF
EAX=9397e6a0 ECX=000031bf EDX=7fffffff EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e246 B9 00 00 00 80 mov ecx, 0x80000000
EAX=9397e6a0 ECX=80000000 EDX=7fffffff EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e24b 0F 46 F2 cmovbe esi, edx
EAX=9397e6a0 ECX=80000000 EDX=7fffffff EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e24e 89 CA mov edx, ecx
EAX=9397e6a0 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e250 0F 46 D7 cmovbe edx, edi
EAX=9397e6a0 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e253 89 D7 mov edi, edx
EAX=9397e6a0 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e255 E9 01 FF FF FF jmp 0x4038E15B
EAX=9397e6a0 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e15b 8B 45 00 mov eax, [ebp]
EAX=20080000 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e15e 89 7C 24 0C mov [esp+0x0C], edi
EAX=20080000 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e162 89 74 24 08 mov [esp+0x08], esi
EAX=20080000 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e166 C7 04 24 01 00 00 00 mov dword ptr [esp], 0x01
EAX=20080000 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e16d 89 44 24 10 mov [esp+0x10], eax
EAX=20080000 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e171 8B 44 24 28 mov eax, [esp+0x28]
EAX=403fd2d8 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e175 89 54 24 2C mov [esp+0x2C], edx
EAX=403fd2d8 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e179 89 44 24 04 mov [esp+0x04], eax
EAX=403fd2d8 ECX=80000000 EDX=80000000 EBX=40415cb8 FLAGS=O--A--
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=80000000 EIP=4038e17d E8 BE 18 FC FF call 0x4034FA40
angle1=9397e6a0, angle2=80000000, clipangle=20080000

See the difference ?

Now, before opening the next spoiler that contains the trace of the buggy emitted code, do you guess the issue?

Well, here is the part with the buggy code.
Code:
angle1=9397e6a0, angle2=67915800, clipangle=20080000
Running DynaRec Block @0x4038e151 (0x415f8600) emu=0xa8179390
EAX=00000035 ECX=000031bf EDX=404787ec EBX=40415cb8 FLAGS=-C---S
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e151 39 FE cmp esi, edi
EAX=00000035 ECX=000031bf EDX=404787ec EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e153 89 FA mov edx, edi
EAX=00000035 ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e155 0F 8C CD 00 00 00 jl 0x4038E228
Ask for DynaRec Block creation @0x4038e228
Emitting 172 bytes for 14 x86 bytes
TRACE ----
    e30e1228    MOVW r1, #0xe228
    e3441038    MOVT r1, #0x4038
    e8800ff0    STMIA r0,{r4-r11}
    e5801020    STR r1, [r0, #32]
    e3002001    MOVW r2, #0x1
    e92d0001    STMFD sp!,{r0}
    e30fce98    MOVW r12, #0xfe98
    e34ac804    MOVT r12, #0xa804
    e12fff3c    BLX r12
    e8bd0001    LDMFD sp!,{r0}
----------
0x4038e228: 8D 83 90 75 FE FF lea eax, [ebx-0x18A70]
    e3082a70    MOVW r2, #0x8a70
    e3402001    MOVT r2, #0x1
    e0474002    SUB r4, r7, r2
TRACE ----
    e30e122e    MOVW r1, #0xe22e
    e3441038    MOVT r1, #0x4038
    e8800ff0    STMIA r0,{r4-r11}
    e5801020    STR r1, [r0, #32]
    e3002001    MOVW r2, #0x1
    e92d0001    STMFD sp!,{r0}
    e30fce98    MOVW r12, #0xfe98
    e34ac804    MOVT r12, #0xa804
    e12fff3c    BLX r12
    e8bd0001    LDMFD sp!,{r0}
----------
0x4038e22e: 89 04 24 mov [esp], eax
    e5884000    STR r4, [r8]
TRACE ----
    e30e1231    MOVW r1, #0xe231
    e3441038    MOVT r1, #0x4038
    e8800ff0    STMIA r0,{r4-r11}
    e5801020    STR r1, [r0, #32]
    e3002001    MOVW r2, #0x1
    e92d0001    STMFD sp!,{r0}
    e30fce98    MOVW r12, #0xfe98
    e34ac804    MOVT r12, #0xa804
    e12fff3c    BLX r12
    e8bd0001    LDMFD sp!,{r0}
----------
0x4038e231: E8 BA 14 FC FF call 0x4034F6F0
    e30e2236    MOVW r2, #0xe236
    e3442038    MOVT r2, #0x4038
    e9280004    STMDB r8!,{r2}
Jump to linker (#0)
    e30fc6f0    MOVW r12, #0xf6f0
    e344c034    MOVT r12, #0x4034
    e30019b0    MOVW r1, #0x9b0
    e34a1848    MOVT r1, #0xa848
    e5912000    LDR r2, [r1]
    e12fff12    BX r2
 --- DynaRec Block created @0x4038e228 (0x415f95e0, 0xac bytes)
EAX=00000035 ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e228 8D 83 90 75 FE FF lea eax, [ebx-0x18A70]
EAX=403fd248 ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e22e 89 04 24 mov [esp], eax
EAX=403fd248 ECX=000031bf EDX=67915800 EBX=40415cb8 FLAGS=O-P---
ESP=405a0750 EBP=40476764 ESI=9397e6a0 EDI=67915800 EIP=4038e231 E8 BA 14 FC FF call 0x4034F6F0
1 angle behind
Ask for DynaRec Block creation @0x4038e236
Emitting 476 bytes for 36 x86 bytes
TRACE ----
    e30e1236    MOVW r1, #0xe236
    e3441038    MOVT r1, #0x4038
    e8800ff0    STMIA r0,{r4-r11}
    e5801020    STR r1, [r0, #32]
    e3002001    MOVW r2, #0x1
    e92d0001    STMFD sp!,{r0}
    e30fce98    MOVW r12, #0xfe98
    e34ac804    MOVT r12, #0xa804
    e12fff3c    BLX r12
    e8bd0001    LDMFD sp!,{r0}
----------
0x4038e236: 8D 86 00 00 00 80 lea eax, [esi-0x80000000]
    e24a4000    SUB r4, r10, #0
TRACE ----
    e30e123c    MOVW r1, #0xe23c
    e3441038    MOVT r1, #0x4038
    e8800ff0    STMIA r0,{r4-r11}
    e5801020    STR r1, [r0, #32]
    e3002001    MOVW r2, #0x1
    e92d0001    STMFD sp!,{r0}
    e30fce98    MOVW r12, #0xfe98
    e34ac804    MOVT r12, #0xa804
    e12fff3c    BLX r12
    e8bd0001    LDMFD sp!,{r0}
----------
0x4038e23c: BA FF FF FF 7F mov edx, 0x7FFFFFFF
    e30f6fff    MOVW r6, #0xffff
    e3476fff    MOVT r6, #0x7fff
TRACE ----
    e30e1241    MOVW r1, #0xe241
    e3441038    MOVT r1, #0x4038
    e8800ff0    STMIA r0,{r4-r11}
    e5801020    STR r1, [r0, #32]
    e3002001    MOVW r2, #0x1
    e92d0001    STMFD sp!,{r0}
    e30fce98    MOVW r12, #0xfe98
    e34ac804    MOVT r12, #0xa804
    e12fff3c    BLX r12
    e8bd0001    LDMFD sp!,{r0}
----------
0x4038e241: 3D FF FF FF 3F cmp eax, 0x3FFFFFFF
    e30f2fff    MOVW r2, #0xffff
    e3432fff    MOVT r2, #0x3fff
    e1a01004    MOV r1, r4
    e92d0001    STMFD sp!,{r0}
    e300ce7c    MOVW r12, #0xe7c
    e34ac805    MOVT r12, #0xa805
    e12fff3c    BLX r12
    e8bd0001    LDMFD sp!,{r0}
TRACE ----
    e30e1246    MOVW r1, #0xe246
    e3441038    MOVT r1, #0x4038
    e8800ff0    STMIA r0,{r4-r11}
    e5801020    STR r1, [r0, #32]
    e3002001    MOVW r2, #0x1
    e92d0001    STMFD sp!,{r0}
    e30fce98    MOVW r12, #0xfe98
    e34ac804    MOVT r12, #0xa804
    e12fff3c    BLX r12
    e8bd0001    LDMFD sp!,{r0}
----------
0x4038e246: B9 00 00 00 80 mov ecx, 0x80000000
    e3005000    MOVW r5, #0x0
    e3485000    MOVT r5, #0x8000

The emitted code is a bit complex here, because to code to emit the Trace is also emitted, and included in the trace. Debugging a Dynarec is a real pleasure...

So the issue is simple: in fact
That instruction: lea eax, [esi-0x80000000] is a bit special.
LEA means "Load Effective Address", and this is supposed to simply put esi-0x80000000 inside eax.
The LEA opcode is normaly LEA Reg, [Reg+Address], if I simplify. And the emitting code had some code to adapt to negative value to emit Sub instead of Add. The issue with 0x80000000 is that this is INT_MIN, the minimum value an int32 can hold, and this particular value cannot be negated! Int32 are from -2 147 483 648 and +2 147 483 647. So I code a special case for this one...
And now PbBoom works fine.
prboomfixed.png

Unfortunately, that didn't fixed the profile issue in WorldOfGoo or the sound issue in SuperMeatBoy.
 
I wonder if you could do this on-the-fly; what I mean; is in a special debug mode, you would essentially generate the dynrec, run up until the next return, when you get there save register state, and do the same thing with the non-dyn-rec and see if the results match. I am obviously massively over simplifying the problem (memory reads/writes would need to be restored, etc. etc.) but it just strikes me there could be an automated way to run through an app/game in this mode and have it log all the times the dyn-rec gets it wrong.
 
I wonder if you could do this on-the-fly; what I mean; is in a special debug mode, you would essentially generate the dynrec, run up until the next return, when you get there save register state, and do the same thing with the non-dyn-rec and see if the results match. I am obviously massively over simplifying the problem (memory reads/writes would need to be restored, etc. etc.) but it just strikes me there could be an automated way to run through an app/game in this mode and have it log all the times the dyn-rec gets it wrong.
Yes, that would be very good for debugging, but indeed, that would need me to track every write to memory, so basically write a memory tracker for each instruction, so some third code per x86 opcode (interpreter / dynarec / tracker), with its own set of bugs...
Amazing...

Respect!
Thanks
 
You are doing fantastic work here! Thank you!

By any chance have you have tried the Steam X86 Linux client?
 
I am still working on the Dynarec for now. Adding now opcode and fixing bugs.
I noticed that SuperMeatBoy in fact doesn't have sound issue (I had put music and sound to 0 in option screen), so this one seems to be working fine. I'll probably do a video later.
UNDERTALE is now working fine. Speed is correct on my Gigahertz model (the loading is a bit long, but at least half of the time are taken by shaders beeing compiled, so it's not linked to box86).

FTL seems much better now, but can use some more optimisations.
Unfortunatly, the save profile issue in WorldOfGoo is still there. I also notice the SwordAndSworcery crash at some point, so more debugging is still needed. Games like Risk of Rain is still a bit slow in game, with choppy music. Not A Hero is also a bit slow in game. Broken Sword 1 Director's Cut Edition is fine and seems playable.
 
Last edited:
You're a Wizard ;)
The Pyra will be an even greater device thanks to your work.

As I'm playing The Elder Scrolls:Skyrim for my first time on the Nintendo Switch right now I wonder if and how well the other Elder scrolls Games might run?
Morrowind?
Any chance to get Oblivion to run?

I hope you won't get bored/tired of improving your great stuff :)
 
You're a Wizard ;)
The Pyra will be an even greater device thanks to your work.
Thank you :)
As I'm playing The Elder Scrolls:Skyrim for my first time on the Nintendo Switch right now I wonder if and how well the other Elder scrolls Games might run?
Morrowind?
Any chance to get Oblivion to run?
Well, both are Windows only app, and for now, Box86 doesn't target Wine.
But there is OpenMW for Morrowind, that should work with a correct framerate on the Pyra (it's too slow on the Pandora, but at least it runs).
Oblivion really needs Wine for now.
I hope you won't get bored/tired of improving your great stuff :)
When things are working, it's fine. When I get bugs over bugs over bugs, it can be tiring...but hopefully, bugs get fixed.
 
Thank you Seb....really a nice surprise, another great game now playable on Pandora (and Pyra).
 
Question is: shall I release some PND for any of the game I mentionned? And if yes, wich one should I do?
(also, latest box86 with dynarec will be in next Codeblocks pnd relase)
 
Back
Top