我正在组装一个“simon”游戏,每当按钮打开时,我都需要发出嘟嘟声,哔哔声也应该彼此不同。 谢谢装配8086 - DOSBOX - 如何产生哔声?
回答
您可以使用speaker保持您的设计简单。
扬声器可让您以不同的频率播放方波,但这更涉及。
扬声器只是一个电磁铁,当电流流过时,它会被拉回,否则它会保持在默认位置。
通过来回移动扬声器,可以创建声波。
扬声器可以手动或通过使用PIT的信道2
端口61H的第0位控制扬声器源(0 =人工,1 = PIT)和位1的相同端口是移动当使用PIT时,“扬声器使能”位(不使用扬声器“位置”)。
这里的一个示意图(从这个page)缺少手工驱动部分:
的PIT经由端口40H-43H控制,我们将使用模式3(方波发生器)的每个时间设定分频器的两个字节。
PIT有一个运行在1.193180 MHz左右的振荡器,分频器用于控制方波周期。
不处理内部事件:在PIT振荡器的每个时钟周期,加载的分频器递减。方波的周期等于PIT将分频器递减到零所需的时间。
产生声音只是使用所需的分频器编程PIT并启用扬声器。
稍后,我们需要禁用它。
一个简单的方法是使用被称为每秒18.2次的int 1ch。
通过在首次播放声音时通过在变量中保存一个持续时间,在int 1ch的每个滴答声处减少该持续时间并在计数达到零时禁用扬声器,可以控制嘟嘟声的持续时间。
使用int 1ch需要设置功能(beep_setup
)和拆卸功能(beep_teardown
)。
BITS 16
ORG 100h
__start__:
;Setup
call beep_setup
;Sample beep of ~2sec
mov ax, 2000
mov bx, 36
call beep_play
;Wait for input
xor ax, ax
int 16h
;Tear down
call beep_teardown
mov ax, 4c00h
int 21h
;-------------------------------------------------
;
;Setup the beep ISR
;
beep_setup:
push es
push ax
xor ax, ax
mov es, ax
;Save the original ISR
mov ax, WORD [es: TIMER_INT * 4]
mov WORD [cs:original_timer_isr], ax
mov ax, WORD [es: TIMER_INT * 4 + 2]
mov WORD [cs:original_timer_isr + 2], ax
;Setup the new ISR
cli
mov ax, beep_isr
mov WORD [es: TIMER_INT * 4], ax
mov ax, cs
mov WORD [es: TIMER_INT * 4 + 2], ax
sti
pop ax
pop es
ret
;
;Tear down the beep ISR
;
beep_teardown:
push es
push ax
call beep_stop
xor ax, ax
mov es, ax
;Restore the old ISR
cli
mov ax, WORD [cs:original_timer_isr]
mov WORD [es: TIMER_INT * 4], ax
mov ax, WORD [cs:original_timer_isr + 2]
mov WORD [es: TIMER_INT * 4 + 2], ax
sti
pop ax
pop es
ret
;
;Beep ISR
;
beep_isr:
cmp BYTE [cs:sound_playing], 0
je _bi_end
cmp WORD [cs:sound_counter], 0
je _bi_stop
dec WORD [cs:sound_counter]
jmp _bi_end
_bi_stop:
call beep_stop
_bi_end:
;Chain
jmp FAR [cs:original_timer_isr]
;
;Stop beep
;
beep_stop:
push ax
;Stop the sound
in al, 61h
and al, 0fch ;Clear bit 0 (PIT to speaker) and bit 1 (Speaker enable)
out 61h, al
;Disable countdown
mov BYTE [cs:sound_playing], 0
pop ax
ret
;
;Beep
;
;AX = 1193180/frequency
;BX = duration in 18.2th of sec
beep_play:
push ax
push dx
mov dx, ax
mov al, 0b6h
out 43h, al
mov ax, dx
out 42h, al
mov al, ah
out 42h, al
;Set the countdown
mov WORD [cs:sound_counter], bx
;Start the sound
in al, 61h
or al, 3h ;Set bit 0 (PIT to speaker) and bit 1 (Speaker enable)
out 61h, al
;Start the countdown
mov BYTE [cs:sound_playing], 1
pop dx
pop ax
ret
;Keep these in the code segment
sound_playing db 0
sound_counter dw 0
original_timer_isr dd 0
TIMER_INT EQU 1ch
特别感谢Sep Roland修复原代码中的缺陷!
您可以使用beep_play
播放一个嘟嘟声,使用的单位是上述硬件配置的“自然”单位。
如果您的频率和持续时间是固定的,这些设备将免费简化代码。
在给定持续时间后蜂鸣声停止,您可以使用beep_stop
强制停止蜂鸣声。
一次播放多个声音是不可能的(甚至在不采用PWM技术的情况下混合它们也是不可能的)。
呼叫beep_play
而另一声嘟嘟声将起到停止当前嘟嘟声并启动新蜂鸣器的作用。
一个很好的答案。 +1但是* beep_isr *中断服务程序存在一个重要问题!你不能只使用'AX'寄存器,而不能保存它。如果你写了:'cmp WORD [cs:sound_counter],0''je_bi_stop''dec WORD [cs:sound_counter]'',解决方法很简单。根本不需要使用“AX”。 –
非常感谢@SepRoland!我正在更新信用的答案:) –
- 1. 使用Raspberry Pi通过压电传感器产生“哔哔声”
- 2. 循环在大会:TASM 8086(DOSBox中)
- 3. 让哔哔声在哔哔声后留言
- 4. 你如何使iPhone哔声?
- 5. IE输入哔哔声
- 6. 装配8086程序 - 装配错误
- 7. 装配8086 - TD卡住
- 8. Java Swing - 如何在任何JOptionPane之前发出哔哔声?
- 9. 如何关闭Eclipse中的哔声?
- 10. 从哔声()中删除睡眠,产生声音的替代方法?
- 11. 下面的代码如何使PC发出哔哔声?
- 12. 没有使用NSBeep()发出哔哔声()
- 13. ALT +快捷键会发出“哔哔”声
- 14. 在InputStream/Scanner中发出哔哔声
- 15. 在Linux中发出哔哔声C
- 16. Xamarin使用哔声()
- 17. 哔声流激活
- 18. 如何在C++中发出长哔声?
- 19. 如何用PyFace发出哔声?
- 20. 如何使Windows服务哔声?
- 21. 如何将SpeechRecognizer的哔声静音?
- 22. 如何在Click Mouse中禁用哔声?
- 23. 无限制系统扬声器哔哔声
- 24. 在程序集中生成声音8086
- 25. DOSBox上的8086程序集:idiv指令的错误?
- 26. 蟒蛇 - 我怎样才能生成一个WAV文件的哔哔声?
- 27. 8086装配时间打印中断
- 28. 在DOSBOX中使用程序集8086相乘
- 29. 鸿沟鸸鹋8086装配误差
- 30. 如何在输入按下时防止文本框发出哔哔声?
[在DOSBox的Sound Blaster设备上播放.wav文件]可能的重复(http://stackoverflow.com/questions/41359112/playing-wav-files-on-dosboxs-sound-blaster-device) –
您是否咨询过一个DOS中断引用? – Michael