Skip to content

Fix several real-mode DOS program compatibility issues#38

Closed
emendelson wants to merge 3 commits into
cracyc:vtfrom
emendelson:dos-compat-fixes
Closed

Fix several real-mode DOS program compatibility issues#38
emendelson wants to merge 3 commits into
cracyc:vtfrom
emendelson:dos-compat-fixes

Conversation

@emendelson

Copy link
Copy Markdown

Three independent fixes found while getting Word for Word (DOS) and the WordPerfect Office editor to run:

  1. i386: ignore a bogus LOCK prefix on a non-lockable opcode instead of raising #UD. Some DOS programs (e.g. the Word for Word conversion modules, which contain "LOCK CMP") carry redundant prefixes and rely on them being ignored, as other emulators do. Gated behind TOLERATE_BOGUS_LOCK_PREFIX.

  2. msdos: preserve the parent's BP/SI/DI and clear the carry flag when a child process terminates (the INT 21h/4Bh EXEC return). Real DOS preserves the caller's registers across EXEC; leaving them as the child's values crashed parents whose post-EXEC epilogue does "mov sp,bp / pop bp / retf", and a stale carry flag made them treat the EXEC as failed.

  3. msdos: keep the INT 10h FE/FF (TopView/DESQview) shadow buffer mirrored to the console after the program's first FF. WordPerfect writes some updates (e.g. the F5/F7 status-line prompts) straight to the buffer without a following FF and relies on it being live.

Three independent fixes found while getting Word for Word (DOS) and the
WordPerfect Office editor to run:

1. i386: ignore a bogus LOCK prefix on a non-lockable opcode instead of
   raising #UD. Some DOS programs (e.g. the Word for Word conversion
   modules, which contain "LOCK CMP") carry redundant prefixes and rely
   on them being ignored, as other emulators do. Gated behind
   TOLERATE_BOGUS_LOCK_PREFIX.

2. msdos: preserve the parent's BP/SI/DI and clear the carry flag when a
   child process terminates (the INT 21h/4Bh EXEC return). Real DOS
   preserves the caller's registers across EXEC; leaving them as the
   child's values crashed parents whose post-EXEC epilogue does
   "mov sp,bp / pop bp / retf", and a stale carry flag made them treat
   the EXEC as failed.

3. msdos: keep the INT 10h FE/FF (TopView/DESQview) shadow buffer mirrored
   to the console after the program's first FF. WordPerfect writes some
   updates (e.g. the F5/F7 status-line prompts) straight to the buffer
   without a following FF and relies on it being live.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cracyc

cracyc commented Jun 16, 2026

Copy link
Copy Markdown
Owner

i386: ignore a bogus LOCK prefix on a non-lockable opcode instead of raising #UD

What does "-i ignore invalid instructions" do in this case?
Also can the excessively verbose comments be cut down a bit?

The SFT block header advertised a hardcoded FILES=20 regardless of the -f option, so programs that require more open files (e.g. WordPerfect 5.1, which needs FILES>=25) refused to run even when -f was raised. Report max_files instead so -fN is actually honored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cracyc

cracyc commented Jun 17, 2026

Copy link
Copy Markdown
Owner

(e.g. WordPerfect 5.1 needs FILES>=25)

Huh? WP51 works fine for me without needing this.

@emendelson

Copy link
Copy Markdown
Author

(e.g. WordPerfect 5.1 needs FILES>=25)

Huh? WP51 works fine for me without needing this.

Ah! It's 5.1+ (5.1 Plus) that requires more than FILES=20. The original 5.1 opens without any problems. I use 5.1+ and always came across this problem.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@emendelson

emendelson commented Jun 17, 2026

Copy link
Copy Markdown
Author

What does -i ignore invalid instructions do in this case?

It doesn't help here. -i sets ignore_illegal_insn, and the INT 6 handler then does CPU_SET_EIP(msdos_int6h_eip). msdos_int6h_eip is captured at the top of i386_trap() as m_eip stands when the #UD fires — which is one byte past the rejected opcode: the decoder rejects LOCK CMP right after reading the 3A opcode, before its ModRM byte. So -i resumes execution in the middle of the instruction, decodes the CMP's ModRM byte as a fresh opcode, and desyncs the stream — the comparison never runs and everything after it is misdecoded. So -i can't make a program containing LOCK CMP actually work; it just converts the #UD into corrupted execution.

-i is also a global "skip any invalid opcode" switch (for genuinely junk bytes), whereas this is a valid instruction carrying a meaningless prefix that should simply execute — hence dropping the prefix and running it, matching DOSBox et al.

Also can the excessively verbose comments be cut down a bit?

Done — pushed; they're roughly half the length now.

Also: should I divide these into three separate PR's instead of one?

@cracyc

cracyc commented Jun 18, 2026

Copy link
Copy Markdown
Owner

So -i can't make a program containing LOCK CMP actually work; it just converts the #UD into corrupted execution.

Is there a way I can try this for myself?

@emendelson

emendelson commented Jun 18, 2026

Copy link
Copy Markdown
Author

So -i can't make a program containing LOCK CMP actually work; it just converts the #UD into corrupted execution.

Is there a way I can try this for myself?

This seems to be the "illegal instruction" error when I use Word for Word for DOS 7.2 from the Adobe File Utilities: I select a file to convert from the menu, and tell the program to convert the file, and the illegal instruction occurs. (It doesn't occur in DOSBox or vDos.) There is a CD image on Internet Archive:

https://archive.org/details/adobe-file-utilities-mac-win-1996

And I packaged them for use with DOSBox-X here, and this might be the easiest way to get them:

https://mendelson.org/legacyfileconverter.html

The installer will put the complete DOS version into a folder together with the AutoIt script that runs an old version of vDos that runs WFW.EXE.

To produce the "illegal instruction": start WFW from msdos-player; choose a file on the left and a format on the right, and start the conversion. You can get the same error by running the program from the command line, specifying input and output formats, input file and output file.

@cracyc

cracyc commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Just the register save change was enough to fix it for me with the sample.tst file that it comes with. Getting an invalid lock prefix could be a side effect of the corrupt BP register causing it to jump into the weeds.

@emendelson

Copy link
Copy Markdown
Author

Just the register save change was enough to fix it for me with the sample.tst file that it comes with. Getting an invalid lock prefix could be a side effect of the corrupt BP register causing it to jump into the weeds.

The Sample.tst file is the intermediate file that WFW uses. You should get the illegal instruction when you convert a real-world document. I've been trying to use WFW with msdos-player for many years, and only this fix got it working.

@cracyc

cracyc commented Jun 18, 2026

Copy link
Copy Markdown
Owner

I tried a bunch more and they worked fine. Do you have a test case that causes that error?

@emendelson

emendelson commented Jun 18, 2026

Copy link
Copy Markdown
Author

I tried a bunch more and they worked fine. Do you have a test case that causes that error?

Here is one. I used msdos_i486.exe that I built in msys64 and ran wfw.exe. My test file was a WP file (zipped up here):

test.zip

I tried converting to "Target format: MS Word for Windows 6.0 - 7.0" with a DOC extension, and got the error shown here:

Screenshot 2026-06-18 104121

With the version created in the PR (combined with WFW.exe as a single executable), the conversion worked perfectly. Same conversion filters in both tests, and both were run from the same folder.

@cracyc

cracyc commented Jun 18, 2026

Copy link
Copy Markdown
Owner

I tried that one and it works fine. Can you try this build?

w4wmsdos.zip

@emendelson

emendelson commented Jun 18, 2026

Copy link
Copy Markdown
Author

I tried that one and it works fine. Can you try this build?

w4wmsdos.zip

Yes, that build worked, and I can't imagine why mine didn't. BUT: the second time I launched this w4w... build from the same command prompt, it locked up on the Word for Word splash screen. It worked again when I opened a new command prompt.

PS: There's another minor glitch in running WordPerfect or the WP editor which this PR doesn't fix. Should I ask about that in a separate issue, or here?

@cracyc

cracyc commented Jun 18, 2026

Copy link
Copy Markdown
Owner

PS: There's another minor glitch in running WordPerfect or the WP editor which this PR doesn't fix. Should I ask about that in a separate issue, or here?

Better to keep it separate since it's something different so make a new issue.

BUT: the second time I launched this w4w... build from the same command prompt, it locked up on the Word for Word splash screen. It worked again when I opened a new command prompt.

If you are using the windows terminal there was a bug that would cause it to hang with msdos-player that is fixed in 1.23. microsoft/terminal#18117

@emendelson

Copy link
Copy Markdown
Author

BUT: the second time I launched this w4w... build from the same command prompt, it locked up on the Word for Word splash screen. It worked again when I opened a new command prompt.

If you are using the windows terminal there was a bug that would cause it to hang with msdos-player that is fixed in 1.23. microsoft/terminal#18117

Fascinating! Thank you for the link.

@cracyc

cracyc commented Jun 19, 2026

Copy link
Copy Markdown
Owner

I committed the register save fix except the carry flag which may still be needed but it didn't cause problems that I could see. I'm sure the files handling needs fixing but programs that walk the sft are going to be unhappy when they fall off the end of it. Dosbox-x creates a 5 entry sft and adds any additional in a separate block. Although, Dosbox-staging only creates a 16 entry sft and WP51 plus works fine in it so maybe the problem you are seeing is something else. The Topview change seems reasonable too but I would like to check that DOS/V programs which rely on it work properly.

@emendelson

emendelson commented Jun 19, 2026

Copy link
Copy Markdown
Author

I added a comment to the closed issue about the ed.exe last line, because it still isn't fixed, unfortunately. Meanwhile, thank you for the Word for Word fix.

@emendelson

Copy link
Copy Markdown
Author

About the FILES issue that I've been wasting your time by asking about when you already answered...

My AI collaborator (Claude Code) suggests that I post this, and I hope I'm not crossing any lines by doing so:


You're right about walking the SFT — a couple of things I ran into while chasing this that might be useful:

  • The SFT region is currently sized for only 20 entries (SFT_SIZE 0x4b0 /* 6 + 0x3b * 20 */, with DISK_BUF_TOP immediately after it), so bumping just the header count does let a walker run off the end. wp.com is happy because it only reads the count, not the chain — which is why -f30/-f40 got WP 5.1+ / 6.x past their "needs more FILES" check and starting.

  • Related heads-up: there's already a latent overflow in that area — msdos_open writes SFT entries at SFT_TOP + 6 + 0x3b*fd for fd up to MAX_FILES (128), past the 20-entry SFT_SIZE, so opening more than 20 handles already scribbles into DISK_BUF/CDS.

So the actual requirement on our end is just that -f<n> controls the reported FILES count (WP 5.1+ wants ≥ 25, the 6.x launcher more). Whichever way you'd rather back that — enlarging the region to MAX_FILES, or the small-first-block + chained-extra approach you mentioned from dosbox-x — works for this purpose; I just wanted to flag the sizing and the existing overflow.


Of course I don't pretend to understand this, and probably you have a better solution in mind, but of course I'll be happy to test anything you post.

@cracyc

cracyc commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Well, dosbox (and dosbox-staging, the 16 is for something else) claims to have 200 sft entries so I guess there aren't many if any programs that walk the sft which means it just might not be an issue.

Related heads-up: there's already a latent overflow in that area — msdos_open writes SFT entries at SFT_TOP + 6 + 0x3b*fd for fd up to MAX_FILES (128), past the 20-entry SFT_SIZE, so opening more than 20 handles already scribbles into DISK_BUF/CDS.

Wow, this is a hallucination. SFT_TOP + 6 + 0x3b * fd is in three places, none of them are msdos_open and they all check that fd < 20.

@cracyc

cracyc commented Jun 20, 2026

Copy link
Copy Markdown
Owner

I think everything here has been taken care of.

@cracyc cracyc closed this Jun 20, 2026
@emendelson

Copy link
Copy Markdown
Author

WP 5+ runs as expected with -f25. Thank you!

@emendelson emendelson deleted the dos-compat-fixes branch June 24, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants