It seems that you're using an outdated browser. Some things may not work as they should (or don't work at all).
We suggest you upgrade newer and better browser like: Chrome, Firefox, Internet Explorer or Opera

×
I have some programming experience, including tinkering with DOSBox and a number of computer game source ports, and I'm curious about SHLINK from this perspective. I did look at the source code, unfortunately its low level C and assembly is a bit beyond me.

The page claims this:

I started to code a loader to run SS natively under win32. It basically acts as some kind of layer between SS and Win32, in order to fool SS into thinking it's running under DOS. There is no emulation, game runs full speed.


This sounds like a clumsy way of explaining what an emulator is to a non-technical audience. But the page expressly says that it isn't an emulator. This explanation isn't satisfying to me. Making a DOS executable work on Windows is no trivial task that you can bypass by lying to the program about the OS version (this is how Windows Compatibility Mode often works, BTW). Memory management is totally different, hardware calls are direct, and the DOS API has zero compatibility with any 32-bit Windows API. This is why DOSBox rocks so much, and why we'd be nowhere without it.

I only comprehend two ways of getting a 16-bit DOS game to work on Windows; you can recode the engine and compile it to native 32-bit Windows assembly, or you can simulate a DOS environment, including legacy hardware like the Sound Blaster 16. The former approach is nearly impossible to do accurately without having the original source code, and the source for SHLINK doesn't look like it's doing that at all. The latter approach is, in my mind, emulation. I know there's some debate over what counts as emulation and what counts as virtualization, but I don't see a clear line between them, so I tend to group them all under 'emulation' if there's any debate.
This question / problem has been solved by Winterfuryimage
I'd love to know too! Yeah, that description does indeed sound like it's an emulator, other than the part where he says it's not an emulator lol.

(How the heck do I get notified about forum updates on here? :-)
Shlink kind of simulates OS loader by reading the SS1's executable code into memory and doing what OS loader usually does (relocations, etc). It then patches the DOS specific code, strategically placing jump and/or call commands to its own routines (sort of like hooking) which simulate the function of the original OS specific code. Finally, it gives control to the patched code and it runs natively.
dosbox has to emulate x86 cpu, this engine doesn't
If you're interested you can take a look at the Syndicate Wars port here. The approach used by its authors is quite similar. Shlink replaces the DOS-specific parts 'dynamically' after loading the original executable file into memory, while the authors of the Syndicate Wars port opted for a 'static' approach - they disassembled the game's code, located and replaced the DOS-specific code and then compiled it back.

There's a where Unavowed and Gynvael Coldwind (the authors of the SW port) explain the method they used and there are also [url=http://recon.cx/2010/slides/recon_swars.pdf]slides.
Post edited September 23, 2015 by Winterfury
The part where you say "it patches the DOS specific code" confuses me. I've coded in real mode DOS assembly before - nothing nearly as complex as System Shock (my biggest project was a kind of lame Elite clone, monochrome vector graphics and no sound) - and every single line I wrote was DOS specific. And I'd expect the complexities of late-era DOS games, the hideously complicated protected mode memory management, the direct hardware calls, the weird SVGA modes, to be even more deeply ingrained in the DOS conventions, not less.

A concrete example - how would it play sound effects? The original, unpatched code would contain instructions for reading a resource file (probably using a DOS API) and translating it into instructions meant for SB16 hardware. Windows has no method of intercepting DOS API calls, and instructions meant for SB16 hardware would be meaningless to any Windows sound API.

On a related note, System Shock's music, though stored in MIDI format, is actually meant to be heard on an SB16 and not a GM device. Unlike SB16 instructions, Windows can play back MIDI natively, but in System Shock's case it won't sound right. SHLINK just plays back the MIDI natively, right? For me, it's either emulate/simulate SB16 synth, or bust. None of this fancy MUNT or BASSMIDI for me either, though I'll certainly use it for games composed with MIDI in mind, which includes most of them.
The thing is, SS1 isn't a real mode DOS program which is what makes the magic possible. It's a 32-bit protected mode program running under control of the DOS4G DOS extender, which provides a (zero based) flat memory model. If it were a 16-bit real mode program, the kind of trick the Shlink's author pulled would be impossible due to the segmented memory model.

Take a look at this screenshot showing a fragment of the SS1's disassembled code. You can see that IDA Pro (the disassembler) recognized the fopen library function at the address 93F09h. Since we're dealing with a DOS program, this function probably uses int 21h/ah=3Dh DOS service call to open a file and to make this function work in Windows we have to replace this DOS specific code with the one that would work in Windows. How do we do this? Well, we can do this by writing a replacement function which takes exactly the same arguments (in this case we have two arguments - name of the file to open and mode) and calls Windows API function CreateFile. The new function also has to use the same calling convention as the function it has to replace, in this case the arguments to fopen are passed in registers so the new function has to get its arguments the same way (I think the main reason Shlink's author used Open Watcom compiler is because it lets you define your own calling convention easily by the means of #pragma aux directive). We then have to patch the original function to redirect control to our function. We simply insert jmp instruction (followed by our function's address) at the address 93F09h (the start address of fopen) and each time fopen gets called, our function will take control. This is how we intercept calls to fopen.

Now if you take a look at the file calls.txt from Shlink's source code, you'll find this line:

$1:083F09 %fopen_

The IDA Pro loaded the executable at the base 10000h, hence the difference. I haven't studied Shlink source code yet, but I believe the line tells Shlink's custom linker/patcher where to insert the jump instruction (the address 83F09h) and also the destination of the jump (the fopen_ is probably the name of the replacement function).

As for the sound effects, the game uses the well known Miles Sound System library which provides sort of a high level API. My guess would be that the API functions are intercepted and dealed with in the similar fashion to the example above.
avatar
ikantspelwurdz: On a related note, System Shock's music, though stored in MIDI format, is actually meant to be heard on an SB16 and not a GM device. Unlike SB16 instructions, Windows can play back MIDI natively, but in System Shock's case it won't sound right. SHLINK just plays back the MIDI natively, right? For me, it's either emulate/simulate SB16 synth, or bust. None of this fancy MUNT or BASSMIDI for me either, though I'll certainly use it for games composed with MIDI in mind, which includes most of them.
Ah, this is where it really gets interesting. The thing is, while SS1's music is indeed MIDI, it's in MSS's proprietary XMI (Extended MIDI) format which, as the name suggests, is an extension to MIDI. And it just so happens that SS1 is probably the only game making use of its more advanced features. It's probably the reason why Shlink's author had such a difficulty implementing support for music. I would certainly love to take a look at the updated source code of Shlink the Enhanced Edition is based upon or at least hear some details. Did the author of Shlink get a sudden bout of inspiration or was it done by someone else? I would really love to know.
Post edited September 23, 2015 by Winterfury
avatar
Wolf3: (How the heck do I get notified about forum updates on here? :-)
Unless some has replied to you or quoted you, you don't. =[
Your best bet is to "fav" them (tick the "This is my favourite topic" box on the top right of any topic page (or any game subforum page), then check periodically on the "Community" page to see what threads/forums have had new posts. Otherwise, maybe you can pester someone like adaliabooks to make some sort of script for providing notifications? I don't even know how feasible that would be, though.
Post edited September 23, 2015 by HunchBluntley