1

I’ve been trying to write a small program producing some sound as an example for my students who currently learn x86 assembly programming in real mode. It succeeds playing sound when run from DOSBox but fails when run in NTVDM (I use Windows XP’s one).

The same trouble with attempts to access Sound Blaster in so-called direct mode (with DSP reset performed). The only DSP command that seems to work reliably for me in NTVDM is 0xE1 — retrieving DSP version info.

Most of the MS-DOS programs I have that used to produce non-internal-speaker sounds don’t work in NTVDM either. Except a few of them which happily do.

I had a similar problem with internal speaker output a few years ago, and it turned out then that the order of performing several initialization tasks that seemed exchangeable matters in fact. But this time I can’t find any solution.

Here’s a test piece of code I have (FASM syntax):

    include 'macro\proc16.inc'

MIDIPORT_DATA           = $0330
MIDIPORT_COMMAND        = $0331

        org 100h

Start:
        stdcall MIDI.Initialize

        stdcall MIDI._WriteData, $C0
        stdcall MIDI._WriteData, $00

        stdcall MIDI._WriteData, $90
        stdcall MIDI._WriteData, 60
        stdcall MIDI._WriteData, 127
        xor     ax, ax
        int     16h
        ret

proc MIDI._WriteCommand\
     bValue

     mov        dx, MIDIPORT_COMMAND
@@:
     in         al, dx
     test       al, $40
     jnz        @B

     mov        ax, [bValue]
     out        dx, al
     ret
endp

proc MIDI._WriteData\
     bValue

     mov        dx, MIDIPORT_COMMAND
@@:
     in         al, dx
     test       al, $40
     jnz        @B

     mov        dx, MIDIPORT_DATA
     mov        ax, [bValue]
     out        dx, al
     ret
endp

proc MIDI.Initialize
     stdcall    MIDI._WriteCommand, $FF
.WaitAck:
     mov        dx, MIDIPORT_COMMAND
@@:
     in         al, dx
     test       al, $80
     jnz        @B

     mov        dx, MIDIPORT_DATA
     in         al, dx
     cmp        al, $FE
     jne        .WaitAck

     stdcall    MIDI._WriteCommand, $3F
     ret
endp

What could be the reason? Any suggestions are appreciated.

  • 1
    Windows's NTVDM SoundBlaster emulation is terrible unfortunately. You can try using VDMSound which replaces it with a much better emulation though even that has limitations. Your best bet is to stick with DOSBox as its SoundBlaster emulation is better than some actual SoundBlasters. – Ross Ridge Apr 22 '16 at 03:09
  • @RossRidge, the funny fact is that VDMSound didn’t work either. I could definitely use DOSBox, but can’t let myself since, hey, a few programs like, say, Doom, produce sound successfully even with NTVDM. There might me something… Call it a wish to get more style points :-) – Dmitry Vasiliev Apr 22 '16 at 09:48
  • There are apparently bugs in NTVDM itself that preventing the MPU emulation from working in intelligent mode. The Wikipedia article mentions this and other limitations: https://en.wikipedia.org/wiki/VDMSound#Limitations. – Ross Ridge Apr 22 '16 at 16:27
  • @RossRidge, thanks, that’s one more piece of the puzzle. I’ve found a **really weird** way to make it work though, and I’m currently trying to find out more about possible reasons. It turns out that swapping the 0xC0 message (change instrument) with 0x90 (press key) makes the program produce the sound. Besides, when running the program as in my question in Turbo Debugger, then (after it finished its execution) restarting it with Ctrl+F2, the 2nd, 3rd, etc. attempts succeed. So, I guess, it also has to do something with either internal state of MPU or timing issues. Digging it deeper… – Dmitry Vasiliev Apr 22 '16 at 22:47

0 Answers0