Baron-von-Riedesel / VSBHDA

Sound Blaster emulation for DOS
64 stars 3 forks source link

System Lockup on IBM Thinkpad T41 when realmode enabled. #4

Closed tedkotz closed 9 months ago

tedkotz commented 1 year ago

Love the project. I am trying this out on 2 old laptops I have here and generally great work. VSBHDA works a lot better for me than SBEMU with the games included with FreeDOS, which crash if you use the version of JEMMEX included with SBEMU. The fact this comes with the full replacement of jemmex executables is great.

What Works: If I perform all the steps in the bat file except loading the VSBHDA.exe the system behaves fine (obviously no sound) If I run VSBHDA with the /RM0 flag the system runs fine has sound in protected mode games like Boom and Doom, but no sounds in older real mode games like wolf3d.

What Fails: If I run VSBHDA without the /RM0 flag it seems to terminate successfully, but the next program that runs locks up the system even if it is something unrelated like opening an editor.

Additional Info: Laptop: IBM Thinkpad T41 Type 2373 OS: FreeDOS 1.3 listpci except: Bus Dev Func Vendor ID Class Sub PIF Rev 000 1F 5 8086 24C5 04 01 00 01 Intel Corporation Multimedia Audio Controller

Jemmex, Mem, Listpci, listvesa and env output attached. MEM.TXT LISTVESA.TXT LISTPCI.TXT JEMMEX.TXT ENVIR.TXT

Baron-von-Riedesel commented 1 year ago

the next program that runs locks up the system even if it is something unrelated like opening an editor.

Ok, if Jemm doesn't tell anything then it's pretty hard to "analyze".

You could try to replace Jemm/JLoad by Qemm and see if that works - but it's unlikely.

spazzylemons commented 9 months ago

Experiencing the same issue on a Thinkpad T61. The system locks up when I try to tab-complete a file name, or right after pressing Enter after typing a command. The program works great when running protected mode only. I'm not having much luck running QEMM in FreeDOS, so I can't say if that would help.

Baron-von-Riedesel commented 9 months ago

The lock almost certainly has to do with the trapping of port 0x0020 ( belonging to the PIC ). If /RM0 isn't set, the port is trapped permanently in v86-mode, and it's determined by software if the I/O instruction is to be suppressed ( it must be suppressed if the IRQ in question is an emulated SoundBlaster IRQ ). For some unknown reason it doesn't work for the Thinkpad.

It's possible to compile the source with switch RMPICTRAPDYN==1 ( see files RMWRAP.ASM and PTRAP.C ). Then the PIC port isn't permanently trapped (in v86-mode) and the machine shouldn't freeze ( instantly ). However, it's unlikely that everything will work then. Most likely the machine will freeze as soon as a real-mode game emits its first sound.

spazzylemons commented 9 months ago

I just tried compiling with RMPICTRAPDYN set to 1, and got interesting results. I briefly tested a few real mode apps and games, and they did not crash or freeze. Instead, Sound Blaster audio comes through when the game tries to play a tone with the PC speaker. I noticed this in both Wolfenstein 3D and Duke 2. When setting sound effects to use the PC speaker in these games, the music would be audible only when a sound effect is supposed to be playing. The PC speaker sound itself does not play.

Baron-von-Riedesel commented 9 months ago

A game is probably not the best test case here. A simple Soundblaster PCM music player (running in v86 mode) might give better hints what's going wrong?

spazzylemons commented 9 months ago

By v86 mode I assume you mean VSBHDA running with real mode enabled, since I'm not well knowledgeable on all aspects of x86 operating modes.

Trying Scream Tracker gave no sound output. When trying Fasttracker 2, I could hear very quiet noise when selecting PC speaker, but no sound at all otherwise, as if the computer was muting and unmuting the audio at the hardware level. Fasttracker would not even let me select Soundblaster as an option -- maybe it was able to detect that there wasn't a real Soundblaster card connected?

spazzylemons commented 9 months ago

To remove any possible other causes I've written a small program to just test my hypothesis. It uses the PC speaker, then the sound card, then both at the same time. Without VSBHDA running, the PC speaker plays. With VSBHDA running, the PC speaker does not play, but sound card output also requires the PC speaker to be playing. I also noticed that this only worked when using headphones, and there was complete silence when using the built-in speakers.

Here's a recording of me executing the program before and after starting the emulator. The audio is quiet because this only happened when using headphones.

https://github.com/Baron-von-Riedesel/VSBHDA/assets/25674682/66505fa8-2918-47f1-b53a-44f97f1ad529

Here's the source code, which I built as a COM file using jwasm:

; simple 16-bit COM program to test VSBHDA real mode support

.model tiny

.data

str_about db 'Press a key to advance test', 13, 10, '$'

str_speaker db 'PC Speaker', 13, 10, '$'

str_opl3 db 'OPL3', 13, 10, '$'

str_both db 'PC Speaker and OPL3', 13, 10, '$'

str_silence db 'Silence', 13, 10, '$'

.code

org 100h

start:
    mov dx, offset str_about
    call print_string

    call speaker_on

    mov dx, offset str_speaker
    call print_string

    call speaker_off

    mov dx, offset str_silence
    call print_string

    call opl3_on

    mov dx, offset str_opl3
    call print_string

    call opl3_off

    mov dx, offset str_silence
    call print_string

    call opl3_on
    call speaker_on

    mov dx, offset str_both
    call print_string

    call opl3_off
    call speaker_off

    mov dx, offset str_silence
    call print_string

    ; exit program
    mov ax, 4c00h
    int 21h

print_string:
    ; print string in dx
    mov ah, 09h
    int 21h
    ; wait for keypress
    xor ah, ah
    int 16h
    ret

speaker_on:
    ; 440 hz
    mov al, 0b6h
    out 43h, al
    mov al, 98h
    out 42h, al
    mov al, 0ah
    out 42h, al
    ; use PIT to run speaker
    in al, 61h
    or al, 3
    out 61h, al
    ret

speaker_off:
    in al, 61h
    and al, 0fch
    out 61h, al
    ret

; Write al to OPL3 register ah
; taken from RADtracker 1.1 player
opl3_write:
    mov dx, 388h
    xchg ah, al
    out dx, al
    rept 6
    in al, dx
    endm

    inc dx
    mov al, ah
    out dx, al
    dec dx
    mov ah, 22
opl3_stall:
    in al, dx
    dec ah
    jnz opl3_stall
    ret

opl3_off:
    mov bl, 0
opl3_reset_loop:
    mov al, 0
    mov ah, bl
    call opl3_write
    inc bl
    cmp bl, 244
    jnz opl3_reset_loop
    ret

; based on shipbrook.net/jeff/sb.html
opl3_on:
    ; reset first
    call opl3_off
    ; then play a test sound
    mov ax, 2001h
    call opl3_write
    mov ax, 4010h
    call opl3_write
    mov ax, 60f0h
    call opl3_write
    mov ax, 8077h
    call opl3_write
    mov ax, 0a098h
    call opl3_write
    mov ax, 2301h
    call opl3_write
    mov ax, 4300h
    call opl3_write
    mov ax, 63f0h
    call opl3_write
    mov ax, 8377h
    call opl3_write
    mov ax, 0b031h
    jmp opl3_write

end start
Baron-von-Riedesel commented 9 months ago

I've written a small program to just test my hypothesis.

What exactly is your hypothesis? Regrettably, when I listen to your audio sample, I'm unable to hear much - so I have no clue what this is to prove.

Additionally, there's no connection to the "Lockup" in real-mode, AFAICS.

It's also pretty unlikely to be an SMM issue, since the problems occurs in v86-mode only, not in protected-mode...

spazzylemons commented 9 months ago

From my testing, the OPL3 sound is only audible when the PC speaker is playing. I wonder if it's due to some special handling of the PC speaker by the Thinkpad, or maybe it has to do with the PIT, but I suppose it's most likely a side effect of some more reasonable issue. I haven't yet tested the PCM player you sent because I just noticed it in my inbox, but I'll test that shortly.

Baron-von-Riedesel commented 9 months ago

That PCM player exists in 2 variants, one for protected-mode, the other for v86-mode. The first thing is to test if they behave differently - this shouldn't be.

spazzylemons commented 9 months ago

Just tested the PCM player, and some other apps too. Turns out that for me adding /O1 makes the program (the version with RMPICTRAPDYN set to 1) work perfectly. Sound plays from the built-in speakers, or headphones when plugged in. The default of /O0 results in the strange PC speaker mute effect. Before testing the real mode here I was using a different script which was already configured to /O1, so maybe that's just something I need to do for my setup, and that adding RMPICTRAPDYN fixes the problem. If it's necessary in some circumstances to have dynamic traps disabled, perhaps it could be a command line parameter?

In short -- RMPICTRAPDYN fixed it for me and I didn't realize because I had the wrong output selected

Baron-von-Riedesel commented 9 months ago

If it's necessary in some circumstances to have dynamic traps disabled, perhaps it could be a command line parameter?

No, that's not a valid "fix". There's likely a bug somewhere ( SB emulation or QPIEMU.DLL or Jemm ). That's why to check if the lockup also occurs with Qemm would have been most interesting.

spazzylemons commented 9 months ago

For what it's worth, SBEMU's real mode support, at least last time I tried it with wolf3d, worked on my machine. I don't use it because most stuff I tried it with crashes, so I don't know if it's doing something right or if it's game-specific hacks. I'll try it out some more when I get the chance, including the PCM player you sent.

Baron-von-Riedesel commented 9 months ago

For what it's worth, SBEMU's real mode support, at least last time I tried it with wolf3d, worked on my machine.

I guess that's because SBEMU, unlike the standard VSBHDA, does not permanently trap the PIC port 0x0020.

spazzylemons commented 9 months ago

No, that's not a valid "fix".

Why not? What if some systems don't let you permanently port trap the PIC? Is it possible you're not supposed to permanently port trap the PIC? Again, apologies for not fully understanding the low level concepts, so I'm probably wrong, but if it works, it would be nice to have. Admittedly it is kind of a hack.

There's likely a bug somewhere ( SB emulation or QPIEMU.DLL or Jemm ).

Is it necessary to use QEMM for real mode? Considering how lightweight the QPIEMU shim is, could it be possible to use Jemm for both, to reduce the search space for bugs?

Baron-von-Riedesel commented 9 months ago

What if some systems don't let you permanently port trap the PIC?

Pretty unlikely, because that's what all Windows versions for 80386+ do. So this approach should also work for the Thinkpad.

Baron-von-Riedesel commented 9 months ago

Well, I checked the port 0x20 trapping with DEBUG. The I/O simulation for IN and OUT did modify parts of register AX that should have remained constant - both with QPIEMU.DLL and Qemm. So rmtrap.asm had a bug and has been fixed.

There's a chance that this fixes the Thinkpad lockup.

spazzylemons commented 9 months ago

I'll give it a try and see how it goes

spazzylemons commented 9 months ago

The fix seems to work from my quick testing. Full sound and no lockups!

Baron-von-Riedesel commented 9 months ago

The fix seems to work from my quick testing. Full sound and no lockups!

Good! I think it's time for a new vsbhda release in a few days.

tedkotz commented 7 months ago

Thanks. I finally got some time to come back and looks at this and can confirm everything works great with the latest 1.4 release. Thanks, again.