VOGONS


New Patch - The Hobbit (1983) on 386+ CPUs

Topic actions

First post, by DivByZero

User metadata
Rank Newbie
Rank
Newbie

On my continuing quest to get my full list of classic games working on my 486 retro box, I've prepared another new patch, this time for the DOS text adventure game "The Hobbit", circa 1983. This game was unplayable on anything above a 286, with the game locking up right at the start with only the text "You are an" present. Turns out this one was due to polymorphic code and the prefetch cache. Notes from the patch below:

# This patch modifies HOBBIT.DAT from the 1983 DOS release of "The Hobbit" to fix a prefetch issue causing
# the game to crash on 386 or newer CPUs. This results in the game locking up as soon as it brings up the text
# interface, possibly with the text "You are an" being the only thing shown. The game was originally written
# for the 8086, which had a prefetch queue of 6 bytes. When the 386 came out, that increased to 16 bytes. The
# Hobbit used code which modified instructions only a few bytes ahead, with two NOP instructions (0x90) inserted
# between them to just reach the 6 bytes space required. This was insufficient on the 386, and the old data was
# stuck in the prefetch queue, causing the code to malfunction. This fix replaces the two successive NOP
# instructions with a branch instruction past itself. Since branches invalidate the prefetch queue, this flushes
# the old data from the queue and ensures the newly modified opcodes are read in instead.

Like my other patches, I kept the patch in python since it's transparent and self-documenting. If someone has a question about this 10 years from now, if I just drop an opaque 16-bit binary, that's going to be a pain. This script on the other hand does everything using a few regex expressions. As a python script, you won't be able to run this from dos, but once the files are patched you just need to transfer them onto your DOS machine.

Anyway, that's about it. Let me know if there are any questions or issues.

Reply 2 of 27, by carlostex

User metadata
Rank l33t
Rank
l33t

This is amazing work!!!!

What other titles are in your list? Are you just fixing crashes? Speed sensitivity?

Reply 3 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie

It doesn't look like I have the ability to edit my posts here, but I've got an update for this patch. I noticed today that the "save" and "load" features for this game intermittently fail. Turns out there's a bug in the HOBBIT.COM loader, where the instructions like "mov [edx], al" are executed, but only the lower 16 bits of EDX have been initialized, so unless the upper 16 bits are 0 going into the routine it'll die. I've updated a new patch and attached it to this post, which will correct both the polymorphic code issue in HOBBIT.DAT, and the save/load routines issue in HOBBIT.COM.

This does create a bit of a mystery though. The HOBBIT.COM loader contains instructions which were only added in the 386 processor. The 386 came out in 1985, while the DOS version of this game apparently came out in 1984. Unless that's incorrect and it actually came out in very late 1985, and required a minimum 386 processor, it means all the commonly available sources which contain to have the DOS version of "The Hobbit" are probably not the original version of this game. Possibly this was a later version or update. The box release of this game looked like this:
https://www.ebay.com/itm/335776788781
https://www.ebay.com/itm/205142392987
Manual is here:
https://www.mocagh.org/tolkien/hobbit-manual.pdf
The manual shows it was created by Melbourne House, and the loader has the same origin, as evidenced by the "THE HOBBIT by Melbourne House. Dos driver by Mok." string embedded into it. I strongly suspect however if someone was to take an image of the original disk from a 1984 release however, it would not match the files that are commonly floating around the web.

At any rate, here's an updated, and I believe, complete fix for this game on newer systems. I'll probably take a look at "The Fellowship of the Ring" after this and see what state it's in.

Reply 4 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie
carlostex wrote on 2025-05-29, 13:37:

This is amazing work!!!!

What other titles are in your list? Are you just fixing crashes? Speed sensitivity?

I'm actually pretty much at the end of my personal list now. My goal has been to get everything I played as a kid, plus a bunch of stuff I missed that I hand picked, running on a genuine 486DX2 box, from a single launch config in real mode (IE, no EMM386). As of this game, I've actually achieved that. There are a couple of other games I've patched in recent days I haven't shared patches for here (1983 Atari Galaxian, and 1982 Anti-Ballistic-Missile), but I haven't made a proper patch script for them and wanted to check over the logic of the changes a bit more. Apart from that, I'm pretty much done, got everything on my current hit-list (223 games) working. Any requests? Happy to take on a challenge if there's something out there causing issues.

I'll post more about my launch config at some point, because it's really useful I think, and from what I can tell nobody has done it before, as I had to work with the author of JEMM386 to get the load/unload process working so I could switch into/out of Virtual 8086 mode at will (for EMS support):
https://github.com/Baron-von-Riedesel/Jemm/issues/37
Since this seems to have been broken on 486 processors since the unload feature was introduced, and it's not possible to unload EMM386, I can only assume nobody else has tried to do what I'm doing. It's pretty cool being able to have LaunchBox installed and switch between, for example Ultima VII, The Incredible Machine 2, Space Quest 5, Alleycat, Striker, etc without rebooting or leaving the menu.

As for speed sensitivity, when running in real mode (IE, without EMM386 loaded), I've found using ICD.EXE/ICE.EXE to disable/enable the cache, paired with AT-SLOW.COM set properly, can get things perfect in terms of speed. I've got speed configs set for PC-XT and 386, which are the two targets that seem to matter for all the games I tested, and I switch those in and out as needed. The "exit" functionality in AT-SLOW.COM lets me leave any game that didn't have the ability to quit with a few keystrokes too. AT-SLOW.COM only works properly in real mode though, so if you have Jemm or EMM386 loaded, it won't work, which is another reason I wanted to avoid them being on all the time, apart from the crippling performance problems they can create. I'm not planning speed patches for faster systems, simply because I'm not running that config, and I think it's already a pretty well covered area.

Reply 5 of 27, by carlostex

User metadata
Rank l33t
Rank
l33t

Gotcha!!!

Speed sensitive stuff can be a challenge, disabling the cache works well for the most part but you probably know (better than me actually) that disabling the cache will slow down well or not so well, depending on the instruction mix of a certain program. Mostly out there i watch people (youtubers and such), "just disable the caches and you'll get 386 performance" and it's not always like this. Some programs might have an instruction mix or as such that the system will feel more like a 286 and in other cases like a 486.

With ACPI throttling, i noticed something else. We can reduce CPU performance by effectively clocking the CPU lower, but this results by reducing FSB and buses in parallel. Imagine having a Voodoo 3 running on a 3MHz PCI bus. It feels like having 486 with the slowest ISA card ever. This might work well on some scenarios, but not in others.

In a perfect world, game logic should be tied to a constant beat that is similar across all machines but unfortunately that was not to be. However, i understand that is probably impossible to patch games for speed sensitivity with rewriting parts of code. I'm thinking specifically of games like Wing Commander (WC.EXE) and Test Drive 3. Origin did acknowledge this and when they released Secret Missions 2 it came on a different EXE that is not speed sensitive and just runs fine on very fast machines.

In any case, your efforts are extremely valuable, and i hope you can compile a list of games and patches that people can enjoy in the future!

Reply 6 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie

Speed sensitivity isn't so hard to patch for most games IMO, all it requires is to hook into the "main loop" of the target game, and some kind of reference time/timer that can be correlated back to wall clock time. If you're running ahead of what you want, spin until you're within 50% of the sampling time of your target time, then exit your spin loop and resume. I haven't researched the most reliable ways to do a time measurement on DOS, but it's a well trodden area with plenty of materials and code samples. My interest isn't so much with really really fast systems though, and the techniques you'd use to get a 1GHz system to run a game designed for the 386 are different than for a 486, where the overhead you add doing the time sampling might give mixed results, since you can't spin fast enough to get accurate time sampling without overshooting or undershooting wildly from one frame to the next. The results with just turning off the cache aren't sufficient, but turning off the cache gives more predictable execution times, which then allows an interrupt based delay loop with a fixed spin cycle counter calculated for your system, like AT-SLOW.COM uses, to work very reliably indeed. Only problem is, you need to be running in real mode for it to work, which actually isn't a problem if you can do without EMM386 like I have. Any game which needs protected mode or emulated EMS under V86 mode already has its own proper speed throttling. Everything that needs throttling can run in real mode (including WC1), and get synchronization at a rate of 8192 sync points a second, more than enough to get things nicely in sync.

Reply 7 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie

To be clear, I've tested this quite a bit. I've played my 486 off against MartyPC running a number of PC-XT games, which had no speed throttling and relied on 4.77MHz execution speeds. I've got them synced up nicely, just took some comparing and tweaking the delay numbers for my system. I've got a write-back enabled 486 arriving soon, and I'll have to recalibrate when I plug that in in case the numbers shift a bit, but once it's set for a system, it's done. I have that in a central batch file so all the games that are designed for a PC-XT just call a batch file to turn on the delay, then another to turn it off again when they exit. Using launch scripts for each game lets me handle pulling stuff in and out as needed (IE, unload UltraMid for my Gravis when not needed, unl0ad CD drivers for games that don't need it but are conventional memory hogs, etc).

Reply 8 of 27, by carlostex

User metadata
Rank l33t
Rank
l33t

Wing Commander 1, if i remember correctly requires EMS memory, to run in full quality mode. It's not a big deal to disable the cache to make it playable, i actually gone the other way and patched SM2.EXE so it points to the VEGA campaign instead of the Secret Missions 2 campaign. This has a drawback of a couple pilots being replaced by others on the killboard, but i found that an acceptable drawback. Honestly i'd rather play this way than use any sort of slowdown. Wing Commander 1 speed sensitivity is hard to tackle, at one moment during game play is too fast (almost no enemies around) and too slow (lots of enemies around).

So theoretically, i guess it would be possible to add a far JMP to a spin loop attached to, let's say the end of the file add the code there and then count the ticks properly and do a RETF when it's done? My asm is rather limited but i think i got what you said. It's an interesting workaround indeed.

So yeah, that's my 2 cents. I think it was with Alley Cat, the original version was tied to the IBM PC. And then the programmer had access to an IBM AT and he realized he'd better do things properly. That's why Alley Cat still runs well on a fast PC.

Reply 9 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie

Went back and checked my scripts, and yeah, you're right, WC1 needs EMS and I pull that in for it. For that particular game disabling the cache on the 486DX2 was enough to pull it down to effective 386 speeds, so that's what I did for that game, but I haven't played far into it yet or done a proper side-by-side comparison to see how the speed stacks up to the proper rate. Looks like it's the only game on the list of ones I did that required EMS and was also speed sensitive, and could be a good candidate for a patch. It could be easy to fix actually, since SM2.EXE already has speed fixes as you pointed out. Might be possible to prepare a patch for WC.EXE/SM1.EXE based on the changes in SM2.EXE, since they're clearly the same engine with a few internal resource changes and patches if you can just dump the game resources from one into the other. I might have a crack at that.

Reply 10 of 27, by darry

User metadata
Rank l33t++
Rank
l33t++
DivByZero wrote on 2025-05-30, 05:16:
It doesn't look like I have the ability to edit my posts here, but I've got an update for this patch. I noticed today that the " […]
Show full quote

It doesn't look like I have the ability to edit my posts here, but I've got an update for this patch. I noticed today that the "save" and "load" features for this game intermittently fail. Turns out there's a bug in the HOBBIT.COM loader, where the instructions like "mov [edx], al" are executed, but only the lower 16 bits of EDX have been initialized, so unless the upper 16 bits are 0 going into the routine it'll die. I've updated a new patch and attached it to this post, which will correct both the polymorphic code issue in HOBBIT.DAT, and the save/load routines issue in HOBBIT.COM.

This does create a bit of a mystery though. The HOBBIT.COM loader contains instructions which were only added in the 386 processor. The 386 came out in 1985, while the DOS version of this game apparently came out in 1984. Unless that's incorrect and it actually came out in very late 1985, and required a minimum 386 processor, it means all the commonly available sources which contain to have the DOS version of "The Hobbit" are probably not the original version of this game. Possibly this was a later version or update. The box release of this game looked like this:
https://www.ebay.com/itm/335776788781
https://www.ebay.com/itm/205142392987
Manual is here:
https://www.mocagh.org/tolkien/hobbit-manual.pdf
The manual shows it was created by Melbourne House, and the loader has the same origin, as evidenced by the "THE HOBBIT by Melbourne House. Dos driver by Mok." string embedded into it. I strongly suspect however if someone was to take an image of the original disk from a 1984 release however, it would not match the files that are commonly floating around the web.

At any rate, here's an updated, and I believe, complete fix for this game on newer systems. I'll probably take a look at "The Fellowship of the Ring" after this and see what state it's in.

Releasing a game that required a 386 in 1985 would have essentially prevented almost everyone from playing it.

EDIT: I'm confused, I thought the unpatched version of the game would not run on a 286 or better ? How can a game both require a 386 and not run on a 286 or 386. I must be missing something.

BTW, TY for the patch.

Reply 11 of 27, by carlostex

User metadata
Rank l33t
Rank
l33t
DivByZero wrote on 2025-05-30, 15:04:

Went back and checked my scripts, and yeah, you're right, WC1 needs EMS and I pull that in for it. For that particular game disabling the cache on the 486DX2 was enough to pull it down to effective 386 speeds, so that's what I did for that game, but I haven't played far into it yet or done a proper side-by-side comparison to see how the speed stacks up to the proper rate. Looks like it's the only game on the list of ones I did that required EMS and was also speed sensitive, and could be a good candidate for a patch. It could be easy to fix actually, since SM2.EXE already has speed fixes as you pointed out. Might be possible to prepare a patch for WC.EXE/SM1.EXE based on the changes in SM2.EXE, since they're clearly the same engine with a few internal resource changes and patches if you can just dump the game resources from one into the other. I might have a crack at that.

It will be very impressive if you pull it off. If i remember correctly Wing Commander (DOS version) does not have a separate executable for Secret Missions 1. Secret Missions 1 adds some files that WC.EXE already knows how to look for. For the Kilrathi Saga (Windows) Origin did separate them into different executables.

Again if you pull this off, it will be mighty impressive!

Reply 12 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie
darry wrote on 2025-05-30, 16:41:
Releasing a game that required a 386 in 1985 would have essentially prevented almost everyone from playing it. […]
Show full quote
DivByZero wrote on 2025-05-30, 05:16:
It doesn't look like I have the ability to edit my posts here, but I've got an update for this patch. I noticed today that the " […]
Show full quote

It doesn't look like I have the ability to edit my posts here, but I've got an update for this patch. I noticed today that the "save" and "load" features for this game intermittently fail. Turns out there's a bug in the HOBBIT.COM loader, where the instructions like "mov [edx], al" are executed, but only the lower 16 bits of EDX have been initialized, so unless the upper 16 bits are 0 going into the routine it'll die. I've updated a new patch and attached it to this post, which will correct both the polymorphic code issue in HOBBIT.DAT, and the save/load routines issue in HOBBIT.COM.

This does create a bit of a mystery though. The HOBBIT.COM loader contains instructions which were only added in the 386 processor. The 386 came out in 1985, while the DOS version of this game apparently came out in 1984. Unless that's incorrect and it actually came out in very late 1985, and required a minimum 386 processor, it means all the commonly available sources which contain to have the DOS version of "The Hobbit" are probably not the original version of this game. Possibly this was a later version or update. The box release of this game looked like this:
https://www.ebay.com/itm/335776788781
https://www.ebay.com/itm/205142392987
Manual is here:
https://www.mocagh.org/tolkien/hobbit-manual.pdf
The manual shows it was created by Melbourne House, and the loader has the same origin, as evidenced by the "THE HOBBIT by Melbourne House. Dos driver by Mok." string embedded into it. I strongly suspect however if someone was to take an image of the original disk from a 1984 release however, it would not match the files that are commonly floating around the web.

At any rate, here's an updated, and I believe, complete fix for this game on newer systems. I'll probably take a look at "The Fellowship of the Ring" after this and see what state it's in.

Releasing a game that required a 386 in 1985 would have essentially prevented almost everyone from playing it.

EDIT: I'm confused, I thought the unpatched version of the game would not run on a 286 or better ? How can a game both require a 386 and not run on a 286 or 386. I must be missing something.

BTW, TY for the patch.

I know, right? It's a bit weird. I know what I'm seeing on a 486 though. It's clear and straightforward what's wrong. What could be wrong is the information I've read online about the 386 prefetch behaviour, which is undocumented after all. I haven't tested on a 386 to confirm. If a 386 did manage to not trip the bug with the polymorphic code, things would make a lot more sense here. I'd have to test on real hardware to confirm though. No emulators, dosbox included, will accurately emulate hardware prefetch, this would have to be a real hardware test. The loader seems more clear cut though, I don't see how that could ever have worked on a 286, although the timing of the release date of the game vs the 386 CPU seems... odd.

I do have serious questions about the providence of the circulated copies if this game online. A confirmed good dump of the original game disk could help answer a lot of questions. I wonder if the loader of the game is not original, possibly having already been (badly) modified by persons unknown. It doesn't make a lot of sense as things stand. I really don't see how this gave did ever work for anyone on real hardware, at least as it's currently distributed.

Reply 13 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie

Actually, looking at the notes of TDC shows a litany of mentions about loaders by Mok and their various actual processor incompatibilities:
http://www.totaldoscollection.org/nugnugnug/w … s_1981-1989.txt
Seems to confirm that what we're seeing as the reported release of "The Hobbit" online is NOT the real release, possibly a bad port by this "Mok" from one of the other platforms for the earlier 1982 release of the game. It looks to me like the "real PC version" of this game might currently be lost to time.

Reply 14 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie
carlostex wrote on 2025-05-30, 16:54:
DivByZero wrote on 2025-05-30, 15:04:

Went back and checked my scripts, and yeah, you're right, WC1 needs EMS and I pull that in for it. For that particular game disabling the cache on the 486DX2 was enough to pull it down to effective 386 speeds, so that's what I did for that game, but I haven't played far into it yet or done a proper side-by-side comparison to see how the speed stacks up to the proper rate. Looks like it's the only game on the list of ones I did that required EMS and was also speed sensitive, and could be a good candidate for a patch. It could be easy to fix actually, since SM2.EXE already has speed fixes as you pointed out. Might be possible to prepare a patch for WC.EXE/SM1.EXE based on the changes in SM2.EXE, since they're clearly the same engine with a few internal resource changes and patches if you can just dump the game resources from one into the other. I might have a crack at that.

It will be very impressive if you pull it off. If i remember correctly Wing Commander (DOS version) does not have a separate executable for Secret Missions 1. Secret Missions 1 adds some files that WC.EXE already knows how to look for. For the Kilrathi Saga (Windows) Origin did separate them into different executables.

Again if you pull this off, it will be mighty impressive!

I had a bit of a look this morning, and I've successfully identified the added code in the main game loop that adds the speed limit during gameplay in the SM2.EXE binary, and I've been able to patch it out of SM2.EXE in memory during execution to verify it does what I think it does, and removing it makes it run too fast during gameplay like WC.EXE. Looks like it should be easy enough to graft into WC.EXE to make it have the limiting code too. There's already appropriate routines to call, they just weren't used within the main game loop. There's plenty of debug message code I can blat over in the region to cram the extra code into the existing binary without having to mess around too much. I need to make a couple of far calls, but again I think I can get those into the relocation table by cutting some debug code.

This will fix gameplay, but not all the other bits of animation that doesn't have speed limiting in there, like the intro, people talking, pre-mission launch screen, etc, which weren't ever fixed in SM2.EXE. I doubt I'll look at fixing all those, they'll probably be dozens of independent routines that need patching, but it depends how obsessed I get once I start making the changes. I also recall that WC2 had animations that played too fast in the intro as well without throttling the CPU IIRC, although the gameplay was fine. I probably won't actually work on the WC1 patch for another couple of days, it's a busy weekend here and this initial look was all the time I had.

Reply 15 of 27, by amadeus777999

User metadata
Rank Oldbie
Rank
Oldbie

Awesome!

Reply 16 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie
amadeus777999 wrote on 2025-05-31, 09:00:

Awesome!

I ended up getting a couple of hours this evening, so I took a stab at the WC1 speed fix. It's not packaged up into a patch script yet, but here's the proof-of-concept working patched version of WC.EXE. Only actual gameplay is patched, animation sequences will still run too fast, but I may iterate on this patch a bit and fix up those issues too before I properly release it with a script to apply the patch. This patched EXE is from the F3.1 release. Give it a spin, let me know what you think.

Reply 17 of 27, by Errius

User metadata
Rank l33t
Rank
l33t

Thorin sits down and sings about gold.

Is this too much voodoo?

Reply 18 of 27, by carlostex

User metadata
Rank l33t
Rank
l33t
DivByZero wrote on 2025-05-31, 10:25:
amadeus777999 wrote on 2025-05-31, 09:00:

Awesome!

I ended up getting a couple of hours this evening, so I took a stab at the WC1 speed fix. It's not packaged up into a patch script yet, but here's the proof-of-concept working patched version of WC.EXE. Only actual gameplay is patched, animation sequences will still run too fast, but I may iterate on this patch a bit and fix up those issues too before I properly release it with a script to apply the patch. This patched EXE is from the F3.1 release. Give it a spin, let me know what you think.

This is freakin amazing. I'll only have a chance to test it tomorrow (on a Pentium MMX nontheless), i'm working until midnight here today but honestly as long as the gameplay is at normal speed i think people will be happy enough! This is one of the best things the community has ever done, so this effort is very much appreciated. Looking forward to try this.

EDIT: If this works, do you mind i post it at Win Commander CIC? It is a website / community dedicated to Wing Commander games.

Reply 19 of 27, by DivByZero

User metadata
Rank Newbie
Rank
Newbie

Maybe let me wrap the changes into a script first and make a proper thread for it here before sharing it around, that way it'll work for a range of versions and there'll be a proper home for discussion and follow-up here. I should be able to get that done tomorrow.