Последнее MIDI-сообщение не срабатывает, пока не будет отправлено следующее. Может быть, у кого-то был похожий опыт или завалялась какая-нибудь информация по теме.
Написал небольшую программку под MS-DOS, которая играет ноту на MPU-401 через порты $330/$331. На FASM.
include 'macro\proc16.inc'
MIDIPORT_DATA = $0330
MIDIPORT_COMMAND = $0331
org 100h
Start:
stdcall MIDI.Initialize
; Отправка MIDI-сообщения
; Нота = $60, сила_нажатия = 127
stdcall MIDI._WriteData, $90
stdcall MIDI._WriteData, $60
stdcall MIDI._WriteData, $7F
; Ожидание нажатия клавиши
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
.WaitAck2:
mov dx, MIDIPORT_COMMAND
@@:
in al, dx
test al, $80
jnz @B
mov dx, MIDIPORT_DATA
in al, dx
cmp al, $FE
jne .WaitAck2
ret
endp
При запуске из-под NTVDM (Windows XP) звука нет. В DOSBox есть. Если запустить в Turbo Debugger’е, при первом запуске тишина, после перезапуска (не выходя из отладчика) — работает.
В ходе экспериментов выяснилось, что «теряется» последнее сообщение. Например, если добавить отправку ещё одного MIDI-сообщения (перед ожиданием ввода), звук появляется. Но при этом последнее сообщение, опять же, «теряется», пока не будет отправлено следующее.
Многие (но не все!) сторонние программы под DOS, работающие со звуком, в NTVDM молчат.
Версию с буферизацией данных, отправляемых в порт, внутри NTVDM склонен отмести, т.к. в отладчике при втором и последующих запусках работает. Склоняюсь к тому, что есть какая-то особенность в работе эмулируемого MPU-401.
Любая помощь приветствуется.