Sound Blaster emulation in NTVDM: direct mode and MPU don’t work as expected

445 Views Asked by At

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.

0

There are 0 best solutions below