VOGONS


First post, by vanfanel

User metadata
Rank Member
Rank
Member

Hi there,

According to JEMMEX author, the problem with Lemmings 2 on some hardware is that, if Soundblaster is selected as sound device in v86 mode, an exception 0D occurs in Jemm/Qemm ( MS Emm386 hangs ). It's due to a word write access at offset 0xFFFF, something not allowed in true v86 mode ( no problem for DosBox, apparently ).

I would like to hex-edit the game executable and try to get rid of that word write access at offset 0xFFFF: it should be possible.
But how would one go and find what hex position in the game executable file has to be patched?

Thanks!

Reply 1 of 7, by wbahnassi

User metadata
Rank Oldbie
Rank
Oldbie

Run the game under a debugger. The debugger will break on the crash right at the offending instruction. Grab a few bytes of binary code starting from the instruction, and look for it in the executable. If it's not there, then you'll need to find it in one of the game's files which it dynamically loads. Then you can turn that into a NoP and pray it works.

BTW, what you're after is most probably a patch to the game's SB detection routine, which fails on fast CPUs (a very common problem on old games). The write to 0xFFFF is probably not going to be intentional, but a side effect of a failed handshake with the SB. It's timing sensitive, so hopefully your debugger won't slow things down too much and still causes the issue to repro.

Turbo XT 12MHz, 8-bit VGA, Dual 360K drives
Intel 386 DX-33, TSeng ET3000, SB 1.5, 1x CD
Intel 486 DX2-66, CL5428 VLB, SBPro 2, 2x CD
Intel Pentium 90, Matrox Millenium 2, SB16, 4x CD
HP Z400, Xeon 3.46GHz, YMF-744, Voodoo3, RTX2080Ti

Reply 2 of 7, by vanfanel

User metadata
Rank Member
Rank
Member
wbahnassi wrote on 2024-07-10, 10:04:

Run the game under a debugger. The debugger will break on the crash right at the offending instruction. Grab a few bytes of binary code starting from the instruction, and look for it in the executable. If it's not there, then you'll need to find it in one of the game's files which it dynamically loads. Then you can turn that into a NoP and pray it works.

BTW, what you're after is most probably a patch to the game's SB detection routine, which fails on fast CPUs (a very common problem on old games). The write to 0xFFFF is probably not going to be intentional, but a side effect of a failed handshake with the SB. It's timing sensitive, so hopefully your debugger won't slow things down too much and still causes the issue to repro.

I ran l2.exe under Microsoft's DEBUG, and from what I could gather, entering "g"->enter should run the program, but all it does is stall at the blinking DOS cursor.

Maybe other debug program would be preferred for this?

Reply 3 of 7, by vanfanel

User metadata
Rank Member
Rank
Member

Ah, doing

debug l2.com

instead, the game runs, and stalls in the same way as without debug.

But there's no way to stop execution: on GDB, I can return to the debugger, print variables, etc...
How is that done in DOS DEBUG?

Reply 4 of 7, by vanfanel

User metadata
Rank Member
Rank
Member

Ah well, I understood: Microsoft DEBUG included with DOS is only for .COM files.

I guess DOSBOX built-in debugger should be usable for this, too, if I knew what to look for there (the game does not hang in DOSBOX)

Reply 5 of 7, by DivByZero

User metadata
Rank Newbie
Rank
Newbie

This crash isn't due to processor speed. The L2.EXE file is a packed executable, using PKLITE V1.03. The exception is occurring in the unpacking code. It could be an original bug in the PKLITE code, or something unusual with this particular file, but my money is on a bug in PKLITE, which means other games/software from the late 1990s to early 1991 period that uses PKLITE V1.03 could be affected. I haven't looked too closely at the code, because it's easy to bypass. Download UNP 4.01 from here:
https://bencastricum.nl/unp/
Extract the L2.EXE file using the following command:
UNP.EXE e <PathToL2.EXE> <Output.EXE>
Replace the original L2.EXE file with the expanded one. Problem will go away, and it'll work happily with JEMM. Note that EMM386 does manage to deal with this bad write on my 486. Whether it does what it's supposed to is another matter, but EMM386 doesn't get caught up with this (legitimate) issue, just JEMM386.

Reply 6 of 7, by DivByZero

User metadata
Rank Newbie
Rank
Newbie

Oh, I'll add that the note about selecting a sound blaster device is incorrect. This exception is thrown just by running L2.EXE regardless of sound settings, but the base address in memory matters. I was able to get the compressed L2.EXE working by offsetting its loading base address in memory. I suspect the JEMM author saw the crash with one setting and not another due to different base loading addresses between his attempts.

Reply 7 of 7, by vanfanel

User metadata
Rank Member
Rank
Member
DivByZero wrote on 2025-05-28, 23:07:
This crash isn't due to processor speed. The L2.EXE file is a packed executable, using PKLITE V1.03. The exception is occurring […]
Show full quote

This crash isn't due to processor speed. The L2.EXE file is a packed executable, using PKLITE V1.03. The exception is occurring in the unpacking code. It could be an original bug in the PKLITE code, or something unusual with this particular file, but my money is on a bug in PKLITE, which means other games/software from the late 1990s to early 1991 period that uses PKLITE V1.03 could be affected. I haven't looked too closely at the code, because it's easy to bypass. Download UNP 4.01 from here:
https://bencastricum.nl/unp/
Extract the L2.EXE file using the following command:
UNP.EXE e <PathToL2.EXE> <Output.EXE>
Replace the original L2.EXE file with the expanded one. Problem will go away, and it'll work happily with JEMM. Note that EMM386 does manage to deal with this bad write on my 486. Whether it does what it's supposed to is another matter, but EMM386 doesn't get caught up with this (legitimate) issue, just JEMM386.

This is very, very interesting! Can't wait to extract the EXE and try!