dosbox-staging / dosbox-staging

DOSBox Staging is a modern continuation of DOSBox with advanced features and current development practices.
https://www.dosbox-staging.org/
Other
1.29k stars 154 forks source link

1942 - The Pacific Air War Gold - Sound/EMS issue #3920

Closed robrich82 closed 1 week ago

robrich82 commented 2 weeks ago

Are you using the latest Dosbox-Staging Version?

Different version than latest?

0.82.0-rc1

What Operating System are you using?

Windows 11

Whats your question and how can we help?

I bought 1942 The Pacific Air War Gold off GOG. The configuration file provided didn't work in staging so I attempted to figure out why. The game runs if I remove the call to JEMMEX, but then the sound has issues per this thread https://www.vogons.org/viewtopic.php?t=41643

fullscreen = true

[dosbox]
memsize = 32

[dos]
xms = false
ems = false
umb = false

[autoexec]
@ECHO OFF
CLS
C:
CD \MPS\1942
GOTO launcher

:launcher
CLS
ECHO ╔════════════════════════════════════════════╗
ECHO ║ ------------------------------------------ ║
ECHO ║  1942: The Pacific Air War Launcher        ║
ECHO ║ ------------------------------------------ ║
ECHO ║  1) 1942: The Pacific Air War GOLD         ║
ECHO ║  2) Sound Settings                         ║
ECHO ║ ------------------------------------------ ║
ECHO ║  3) exit program                           ║
ECHO ║ ------------------------------------------ ║
ECHO ╚════════════════════════════════════════════╝

CHOICE /c123 /s Which program do you want to run? [1-3]: /n 
if errorlevel 3 GOTO exit
if errorlevel 2 GOTO setup
if errorlevel 1 GOTO game

:game
CLS
JEMMEX.EXE FRAME=E000 LOAD
1942
GOTO exit

:setup
CLS
install.exe
GOTO launcher

:exit
EXIT

Running with this config gives the following output: Screenshot 2024-09-09 163022

If I don't call JEMMEX and enable EMS in the configuration, then the sound doesn't play correctly.

With JEMMEX and the DOSBOX provided with GOG it works as expected.

Code of Conduct & Contributing Guidelines

johnnovak commented 2 weeks ago

@robrich82 Try memsize = 16 as per the linked Vogons thread. If that doesn't work, try 31 too.

robrich82 commented 2 weeks ago

Both 16 and 31 give me the same error unfortunately.

johnnovak commented 2 weeks ago

Both 16 and 31 give me the same error unfortunately.

Could you test it with earlier Staging version? Most likely this is a regression.

MasterO2 commented 2 weeks ago

@robrich82, did you set ems = true in your batch file? The batch file's contents currently has it set to false.

johnnovak commented 2 weeks ago

@robrich82, did you set ems = true in your batch file? The batch file's contents currently has it set to false.

Why should he? The point here is using JEMMEX to get EMS memory instead of the built-in EMS support of DOSBox. That is why you have ems = false in the Vogons thread and the GOG config.

The game must use some non-emulated aspect of EMS memory, hence the need for a native driver.

Grounded0 commented 2 weeks ago

1942: The Pacific Air War (including Gold) how to run added:

https://github.com/dosbox-staging/dosbox-staging/wiki/Game-issues#1942-the-pacific-air-war-including-gold

Please report back did this resolve your issues so others here can decide what to do with this ticket.

johnnovak commented 2 weeks ago

Nice one @Grounded0. This seems like a very unique and interesting game!

interloper98 commented 2 weeks ago

Unfortunately the instructions didn't work because JEMMEX struggles to install itself despite using its flag for virtual machines "noinvlpg". Older releases 0.81, 0.80, and 0.79 had the same issue :cry:, however DOSBox SVN binaries worked! What the heck.

Time to bisect. It landed on 96aaec24a14931cc6c9aa5aab5c7f90c52b1ff42 that added a VMWare mouse interface for Windows 3.1.

This mouse interface sets up an IO port read handler that JEMMEX is not only calling, but calling with the correct magic signature (see my added comments):

static uint32_t port_read_vmware(const io_port_t, const io_width_t)
{
    // JEMMEX makes `reg_eax == VMWARE_MAGIC`, so passes this:

    if (reg_eax != VMWARE_MAGIC) {
        return 0;
    }

    // JEMMEX sets reg_cx == 10, which is VmWareCommand::GetVersion

    switch (static_cast<VmWareCommand>(reg_cx)) {
    case VmWareCommand::GetVersion: command_get_version(); break;
    case VmWareCommand::AbsPointerData: command_abs_pointer_data(); break;
    case VmWareCommand::AbsPointerStatus: command_abs_pointer_status(); break;
    case VmWareCommand::AbsPointerCommand: command_abs_pointer(); break;
    default:
        LOG_WARNING("VMWARE: unimplemented command 0x%08x", reg_ecx);
        break;
    }

    // `command_get_version()` sets reg_eax = 0 and reg_ebx = VMWARE_MAGIC, 
    // and the IO port returns reg_eax which is 0.
    // So it seems JEMMEX doesn't like the modified reg_eax or reg_ebx values.

    return reg_eax;
}

The immediate fix is to set (@Grounded0 , maybe you can add this to the instructions?):

[mouse]
vmware_mouse = false

Looking at eXoDOS, there are 6 games affected:

1942PAW/dosbox.conf:JEMMEX FRAME=E000 LOAD
Charlyt/dosbox.conf:JEMMEX FRAME=E000 LOAD
Kubix/dosbox.conf:@jemmex noems load
SidLin96/dosbox.conf:@jemmex noems load
Thunder/dosbox.conf:JEMMEX FRAME=E000 LOAD
UltFot95/dosbox.conf:JEMMEX FRAME=E000 LOAD
Grounded0 commented 2 weeks ago

I'm sourcing my information from here:

Will add that fix then.

robrich82 commented 2 weeks ago

@interloper98 thanks so much for figuring that out!

Grounded0 commented 2 weeks ago

Fix added.

interloper98 commented 2 weeks ago

@FeralChild64 , it seems like jemmex and the VMware interface are both using the same magic signature and API.

Are there additional criteria the VMware IO read call can check before activiting?

For example, the VMware interface is only used within Windows 3.x, so ideally it should only "come alive" if Windows 3.x is running. Is there a win 3.x signature we can look for?

Another alternative approach would be to acknowledge that this jemmex-vmware clash is truly unique, and therefore the VMware Read IO could check for the presence of jemmex and deactivate if it's present.

Another thought is we could default the VMware interface to false. But that's a bit heavy handed and users settings up the win3.1 driver would need to manually enable this conf setting.

(Or this is a "do nothing": leave this as is and inform jemmex users via the docs and wiki that they need to disable the VMware mouse interface)

FeralChild64 commented 2 weeks ago

Windows tells us when it starts and ends, by calling int 0x2f - see how my WIP branch https://github.com/dosbox-staging/dosbox-staging/tree/fc/mouse-dos-windows-1 is using it. But I’m not sure if this is a good idea, as this interface is also used by the VBADOS mouse driver.

Since JEMMEX is a free and open source tool (in fact, it is still being developed - see https://github.com/Baron-von-Riedesel/Jemm), I would start by checking what JEMMEX is trying to achieve and then make a decision what to do next.

I don’t have access to my PC at the moment - but maybe upgrading the JEMMEX to the latest revision would also help?

Grounded0 commented 2 weeks ago

My instructions currently state that integrated VMWare mouse interface should be off and Jemm should be updated to v5.84.

The original author states that by just updating Jemm to v5.84 and feeding some extra arguments to it is enough to make the game run without issues:

I'd like for people to update to Jemm v5.84 so we don't have to tweak our stuff but someone has to first verify does those original instructions work or not.

FeralChild64 commented 2 weeks ago

@Grounded0 I suggest to first investigate and test, and only then update the Wiki.

——

It seems JEMM is actually trying to detect VMWare - https://github.com/Baron-von-Riedesel/Jemm/blob/34f65c7d680c088a4d741f9baf07822c85333e39/src/INIT16.ASM#L2432 I don’t have more time today for further investigation, unfortunately.

Grounded0 commented 2 weeks ago

I'll drop the first step (integrated VMWare mouse interface off) for now. Others are welcome to test this and edit the Wiki based on evidence gathered through discovery.

robrich82 commented 2 weeks ago

FYI I was already using the latest release of JEMM (5.84) so that doesn't solve the issue by itself.

I changed the command to JEMMEX.EXE D=128 FRAME=E000 NOINVLPG NORAM LOAD and it still didn't solve the issue, I had to do this to make it work still.

[mouse]
vmware_mouse = false
Grounded0 commented 2 weeks ago

Reverted back to previous state based on evidence gathered through discovery.

At least the game now works so you can figure out the rest. ☀️🏖🍷

interloper98 commented 2 weeks ago

Brilliant discovery @FeralChild64 ; we're offering a virtual machine API to provide a direct pass-thru from host to win3.1 at the driver-level for smooth mouse operation... which is then detected by another DOS program! Are we trapped in a cat-and-mouse dance? :yin_yang: :sweat_smile:

Right on @Grounded0 and @robrich82 for clarifying that the latest release of JEMM (5.84) is still affected and doesn't solve this on its own.

johnnovak commented 1 week ago

Another alternative approach would be to acknowledge that this jemmex-vmware clash is truly unique, and therefore the VMware Read IO could check for the presence of jemmex and deactivate if it's present.

Yeah, the ideal approach would be if JEMMEX and the VMware stuff could sort out conflicts automatically between themselves. And it seems JEMMEX is already doing something along those lines, so maybe @FeralChild64 will only need to adjust the VMware API emulation slightly.

Another thought is we could default the VMware interface to false. But that's a bit heavy handed and users settings up the win3.1 driver would need to manually enable this conf setting.

That would be preferable IMO as the VMware mouse stuff is a niche feature only useful for running Win 3.x games in windowed mode. But you could argue this game needs very specific setup steps anyway, so not having to disable the VMware mouse via config wouldn't improve things much. And we're not aware of anything else needing JEMMEX. So it's a toss up.

But I’m not sure if this is a good idea, as this interface is also used by the VBADOS mouse driver.

As above; niche feature. IMO it's OK to require users to explicitly enable very rarely used niche features and this in definitely one of them.

But hopefully getting the VMware API autodetection right would solve this and then the config defaults can stay.

FeralChild64 commented 1 week ago

It seems to me the JEMM only checks for VMWare during the initialization:

;--- VMware detection
;--- questionable, because Qemu "responds" similar to VMware

VMwareDetect proc c

    mov eax, 564D5868h  ;magic number (="VMXh")
    mov cx, 000ah       ;command number (000A=get VMware version)
    xor ebx,ebx         ;command specific parameter
    mov dx, 5658h       ;VMware IO port (="VX")
    in eax,dx           ;"returns" version number in EAX
    cmp ebx, 564D5868h  ;and magic number in EBX (="VMXh")
    setz al
    mov ah,0
    ret

VMwareDetect endp

and:

    invoke VMwareDetect
    .if ax
        mov dword ptr SystemMemory+0E8h, 'VVVV'
        mov dword ptr SystemMemory+0ECh, 'XXXX'
        invoke cprintf, CStr("VMware detected", LF)
    .endif

In plain English: if VMWare interface is found, then assume certain memory layout and mark pages:

Not good… I could probably check the current page name in our VMware interface implementation, and if it’s JEMM386 or JEMMEX, pretend we are not there :D But it would only work in our emulated DOS environment, not when a real MS-DOS / PC-DOS / DR-DOS, etc., is booted.

johnnovak commented 1 week ago

I could probably check the current page name in our VMware interface implementation, and if it’s JEMM386 or JEMMEX, pretend we are not there :D But it would only work in our emulated DOS environment, not when a real MS-DOS / PC-DOS / DR-DOS, etc., is booted.

I don't quite understand the problem from the above description, but that would be much better than nothing. Again, running real DOS is a niche use case, you rarely need that for games which is our no.1 priority.