Воспроизведение звука с помощью динамика P C в сборке x86 - PullRequest
2 голосов
/ 16 января 2020

Итак, я пытаюсь воспроизвести один тональный сигнал с помощью динамика p c в сборке x86. Он воспроизводит звук, но когда я пытаюсь снова его отключить ... Тон начинает делать то, что я могу описать Как сотрясение в main.asm, где я вызываю лейбл sound.asm из

mov cx, 9121
mov bx, 25
call os_play_sound

1 Ответ

1 голос
/ 22 января 2020

Я немного опаздываю на вечеринку, и, возможно, вы, возможно, поняли это, но вот мой ответ для будущих поколений StackOverflow;).

Вы можете протестировать следующий фрагмент (на основе вашего код; немного очищен), который на самом деле издаст тональный сигнал, но подождите, используя INT15H function AX=86H. Обычно это лучше, чем занятое ожидание, но немного хуже, чем перепрограммирование PIT для ваших нужд. Поскольку вы используете MikeOS в качестве основной базы кода, я хотел сохранить код как можно более простым. Комментарии включены для дальнейшего понимания кода.

; ---------------------------------------------
; Generate tone with frequency specified in AX.
; The tone will last for CX:DX microseconds.
; For instance, CX=0, DX=F4240h will play the
; specified tone for one second.
; Registers preserved.

tone:
    PUSHA               ; Prolog: Preserve all registers
    MOV BX, AX          ; 1) Preserve the note value by storing it in BX.
    MOV AL, 182         ; 2) Set up the write to the control word register.
    OUT 43h, AL         ; 2) Perform the write.
    MOV AX, BX          ; 2) Pull back the frequency from BX.
    OUT 42h, AL         ; 2) Send lower byte of the frequency.
    MOV AL, AH          ; 2) Load higher byte of the frequency.
    OUT 42h, AL         ; 2) Send the higher byte.
    IN AL, 61h          ; 3) Read the current keyboard controller status.
    OR AL, 03h          ; 3) Turn on 0 and 1 bit, enabling the PC speaker gate and the data transfer.
    OUT 61h, AL         ; 3) Save the new keyboard controller status.
    MOV AH, 86h         ; 4) Load the BIOS WAIT, int15h function AH=86h.
    INT 15h             ; 4) Immidiately interrupt. The delay is already in CX:DX.
    IN AL, 61h          ; 5) Read the current keyboard controller status.
    AND AL, 0FCh        ; 5) Zero 0 and 1 bit, simply disabling the gate.
    OUT 61h, AL         ; 5) Write the new keyboard controller status.
    POPA                ; Epilog: Pop off all the registers pushed
    RET                 ; Epilog: Return.
...