Change Log

Boxedwine19R1 (svn 966)

Builds (all include Wine 1.7.55 and Wine 4.0)

  • BoxedWine19R1.exe
    Windows installer for 64-bit machines.
  • BoxedWine19R1-32bit.exe
    Windows installer for 32-bit machines, including Windows XP
    Windows 32-bit and 64-bit binaries, no installer. You can download this if you just want the file systems to use if you make your own builds.

2019-09-18 (svn 966)

Changes from 19R1 Beta 2

  • Added new UI to manage games and containers for Windows and Mac builds
  • Added Wine 4.0 file system
  • Windows build can now integrate with the OS to launch 16-bit apps directly from Explorer (Container setting)

2019-08-11 (svn 911)

Changes from 19R1 Beta 1

  • Fixed bugs in the Windows 64-bit build
  • Added support for SSE instructions, and bumped the CPU to be reported as a Pentium 3
  • Enabled support for Direct 3D, this is experimental, so if you are lucky maybe 50% of the Direct 3D games you try will work. You should probably stick to games around the year 2000 or before.


Changes from 18R2

  • Added 64-bit build with a multi-threaded binary translator. This 64-bit should be a lot faster than the 32-bit build.
  • The 64-bit beta build will have some bug and random crashes


Changes from 2018 R1

  • Added support for Wine 3.1 (some games work better, some worse)
  • Added a dynamic recompiler, should be more than 2x faster than 2018 R1
  • No longer uses the -m argument to specify memory, it will be dynamically allocated
  • Supports -bpp 8 command line argument for games that need the emulated desktop to start in 8-bit
  • Fixed some 8-bit color games, like MDK
  • Added Midi support for the Windows build
  • Fixed a floating point issue. Games that used Visual Basic runtime that had an overflow error are fixed by this.

Known Issue

  • Copy/Paste works with Wine 1.6, but broke in Wine 1.7 which is now the default version for the Windows build


  • VideoDD first test

18R1 7.7M Pixels per Second
18R2 19.9M Pixels per Second

  • Quake 2, quake2.exe +timedemo 1 +map demo1.dm2
    18R1 10.0 fps
    18R2 24.5 fps
  • MDK performance test
    18R1 79
    18R2 170


This will take an emulated address that contains emulated x86 code and returns a pointer to a host address containing x64 code.

void* x64CPU::translateEip(U32 ip) {   
    void* result = translateEipInternal(NULL, ip);
    return result;

translateEipInternal is a function that is called recursively to create chunks of x64 code.

translateEipInternal will:

  1. translate a single block (until jmp, call, retn, etc, conditional jumps will not end a block)
    • a) we can’t translate the code after a jmp or call, because it may not be valid (think startup functions that don’t return)
    • b) call/jmp to absolute address will be followed in link (3c below)
    • c) call/jmp to reg/mem and retn will have code inserted to lookup and use the host op address.
      • if the host op address is NULL, then when it is used it will cause an exception that will be handled
      • the handled exception will call translateEipInternal on that address
  2. map each emulated instruction address in the translated block to a host instruction address so that we can find it later
  3. all the jumps that had dummy values placed in them will now be processed (link)
    • a) if the address being jumped to is already mapped to a host instruction, then just use that host instruction
    • b) if the address being jumped to is not valid (emulation memory is not mapped yet), then do nothing for now, this assumes it will be patched later (TODO when I find an example of this where it doesn’t get patched)
    • c) call translateEipInternal on the address being jumped to
    • d) write address into reserved spot

Full code loaded

  • Examples: Most games behave this way
  • This will call translateEip during startup and will translate all the code until a jump/call to a reg or mem is used.

Code with place holders

  • Examples: F16
  • blocks of 0’s will be in the code that get filled in later
  • This is challenging because when this code gets patched by the app, we detect the write to the read only protected emulated memory space then try to re translate this op, since the previous translation was wrong and the patch op is not the same size as the previous op, we will need to re translate the entire block.
  • Will need to make sure the emulated op to host op address mapping gets updated.

Code with simple patches that doesn’t change the instruction the emulated instruction size

  • Examples: Diablo intro movie
  • This is pretty easy to detect. The emulated code page is write protected. When the write exception happens we make the page read/write, then translate just the one or two ops this 1, 2 or 4 byte write affects. The emulated op does not change size so we don’t need to translate any other ops that are not directly affected by this write.
  • The emulated op to host op address mapping does not change
  • If the host instruction becomes small then nop’s will be added
  • If the host instruction becomes bigger, I don’t know what to do yet (TODO when I find an example of this)

Code space get rewritten with new code

  • Examples: None yet
  • This will probably be handled the same as the code with place holders above.


  • Currently if an emulated code page is unmapped, the memory associated with the host code for that page is not free’d. Host code is only free’d when the emulated process is free’d
  • What to do if patched code results in a larger host instruction?
  • What to do if we come across a jmp/call to an absolute address that doesn’t exist? Currently I assume it will be patched later.
  • Figure a way to continue translating a block after a call/jmp, this would result in better performance because it would allow the complete translation of a function where that function would not need to check host to emulation instruction mapping.