Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MMCMP 1.30 crashes DOSBox-X #2549

Closed
sagamusix opened this issue May 24, 2021 · 16 comments
Closed

MMCMP 1.30 crashes DOSBox-X #2549

sagamusix opened this issue May 24, 2021 · 16 comments

Comments

@sagamusix
Copy link

Describe the bug
Trying to compress or uncompress a module file with MMCMP 1.30 crashes DOSBox-X (and also vanilla DOSBox).

To Reproduce
Steps to reproduce the behavior:

  1. Download a module file
  2. Run mmcmp.exe 2nd_pm.s3m
  3. Observe that DOSBox-X crashes.

Expected behavior
File should be processed as expected, and definitely not crash the emulator.

Environment (please complete the following information):

  • Operating system : Windows
  • DOSBox-X release version: 0.83.12

Additional context
MMCMP 1.34 doesn't crash in DOSBox. But I need to run this specific version to test something. Of course it's possible that the program is generally faulty, but either way it should not result in DOSBox crashing.

@Wengier
Copy link
Collaborator

Wengier commented May 24, 2021

I can confirm the crash with MMCMP 1.30:

image

When the program runs the CPU goes to the protected mode, but the gate type 1 is not supported by the CPU_Interrupt() function. On the other hand, MMCMP 1.34 works fine as you said.

@sagamusix
Copy link
Author

I can also confirm that MMCMP 1.30 runs fine on Windows XP 32-bit (inside a VM).

@Wengier
Copy link
Collaborator

Wengier commented May 24, 2021

It does works in a real MS-DOS system, and the issue is related to the CPU code. @joncampbell123 may know the best (and most accurate) way to solve this.

@joncampbell123
Copy link
Owner

Why is INT 21h a 286 Task State Segment, then?

image

@joncampbell123
Copy link
Owner

So, here's about where the problems lie.

Not 100% sure but it might be flawed code that uses protected mode only to try to set up "flat real mode", or at least set FS and GS to 4GB segment limits in real mode.

0823:00000993 0F01E2              smsw dx
0823:00000996 F7C20100            test dx,0001
0823:0000099A 7529                jne  000009C5 ($+29)        (no jmp)
0823:0000099C 6633C0              xor  eax,eax
0823:0000099F 8CD8                mov  ax,ds
0823:000009A1 66C1E004            shl  eax,04
0823:000009A5 660106A400          add  [00A4],eax             ds:[00A4]=000000A8
0823:000009AA 0F0116A200          lgdt word [00A2]            ds:[00A2]=000F
0823:000009AF 66678D4201          lea  eax,[edx+0001]         [illegal]
0823:000009B4 0F01F0              lmsw ax
0823:000009B7 EB00                jmp  short 000009B9 ($+0)   (down)
0823:000009B9 B80800              mov  ax,0008
0823:000009BC 8EE0                mov  fs,ax
0823:000009BE 8EE8                mov  gs,ax
0823:000009C0 0F01F2              lmsw dx
0823:000009C3 EB00                jmp  short 000009C5 ($+0)   (down)
0823:000009C5 C3                  ret

@joncampbell123
Copy link
Owner

joncampbell123 commented May 26, 2021

It's obvious the program is storing the machine status word (which is the same as the low 16 bits of CR0), then loading it to enter 16-bit protected mode, load FS and GS, then loading the original machine status word to reenter real mode.

As far as I can tell in the debugger, DOSBox-X still thinks it's 16-bit protected mode even though LMSW DX loads a DX value with bit 0 cleared which SHOULD exit protected mode on the 386.

Except that it's supposed to be sticky as it was on the 286, because you weren't supposed to exit protected mode on the 286. You were supposed to enter protected mode (set bit 0) and then stay there until reset. So DOSBox-X is technically right, in that LMSW with bit 0 cleared is ignored and protected mode is kept.

@joncampbell123
Copy link
Owner

So then... at some point, Intel allowed LMSW to clear the bit, or maybe the program was written for non-Intel x86 processors. Perhaps 486 and Pentium systems allowed it (I noticed the program executable has a date within the year 1996).

@joncampbell123
Copy link
Owner

DOSLIB task: joncampbell123/doslib#54

@joncampbell123
Copy link
Owner

joncampbell123 commented May 26, 2021

Here's a workaround:

MMCMP has code to detect if the CPU is in Virtual 8086 mode, and it will skip the "flat real mode" code if it detects it.

Try adding this to your dosbox.conf:

[dos]
ems=emm386
emm386 startup active=true

emm=emm386 sets expanded (EMS) memory emulation to run in a manner similar to EMM386.EXE. The "emm386 startup active" option tells EMS emulation to run the whole DOS environment under Virtual 8086 mode. There is even an incomplete VCPI implementation in place (that most DOS extenders are not happy with yet).

@joncampbell123
Copy link
Owner

joncampbell123 commented May 26, 2021

According to the Intel 386 Programmer's Reference Manual, LMSW is not supposed to let you exit protected mode.

Firefox_Screenshot_2021-05-26T17-05-52 676Z

@joncampbell123
Copy link
Owner

But.... I don't see any such remarks in the 486DX programmer's guide. Maybe Intel dropped the set-only behavior for the PE bit starting with the 486. Maybe not.

Firefox_Screenshot_2021-05-26T17-13-27 472Z
Firefox_Screenshot_2021-05-26T17-13-11 005Z

@sagamusix
Copy link
Author

I guess it wouldn't be too unlikely that the program was indeed never able to run on 386s. Version 1.0 was also released in 1996, most people probably were on 486s or Pentiums at that point.

@joncampbell123
Copy link
Owner

The latest commit adds an option to allow/disallow LMSW to clear the PE bit, or "Auto" to pick based on CPU type (486 or higher). The commit at this stage is an educated guess, but it allows MMCMP.EXE to run without crashing.

@Wengier
Copy link
Collaborator

Wengier commented May 26, 2021

I can confirm that MMCMP 1.30 now works fine with the latest code. The Windows binaries based on the updated code are available below in case @sagamusix wants to test the latest pre-compiled builds:

@sagamusix
Copy link
Author

Thanks, I can confirm that it runs fine now.

@Wengier
Copy link
Collaborator

Wengier commented May 28, 2021

Great! Closing the thread.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants