Конференция "Media" » Эмуляция MPU-401 (MIDI) в NTVDM
 
  • Chip&Dale © (23.04.16 17:49) [0]
    Последнее 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.

    Любая помощь приветствуется.
  • Inovet © (24.04.16 09:22) [1]
    Ничё се тема. Не я на уровне порта не пробовал ничего делать. Есть мысль - а не надо ли там ждать готовности к записи нового сообщения путём чтения какого-нибудь бита. Ну это у аппаратного порта если, что там у эмулируемного вообще фиг знает.
  • Inovet © (24.04.16 09:30) [2]
    Так, не особо вникая в код, вроде это делается.
  • Inovet © (24.04.16 09:31) [3]
    Задержку добавить для эксперимента?
  • Chip&Dale © (01.05.16 12:13) [4]
    Готовность (если смотреть по докам) проверяется чтением из порта $0331 (бит 6 должен быть равен 0, если MPU готов принимать данные/команды, бит 7 — если ему есть что отдать). Там в этих процедурах есть соответствующие циклы ожидания.
 
Конференция "Media" » Эмуляция MPU-401 (MIDI) в NTVDM
Есть новые Нет новых   [134427   +37][b:0][p:0.002]