- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在组装一个“simon”游戏,我需要在按钮打开时发出蜂鸣声,蜂鸣声也应该彼此不同。谢谢
最佳答案
您可以使用speaker让您的设计保持简单。
扬声器可让您播放不同频率的方波,it can actually be used to reproduce digital audio但这涉及更多。
扬声器只是一个电磁体,当电流流过它时,它会被拉回,否则它会保持在默认位置。
通过前后移动扬声器,可以产生声波。
扬声器可以手动移动或使用PIT移动的 channel 2。
端口 61h 的位 0 控制扬声器源(0 = 手动,1 = PIT),同一端口的位 1 是使用 PIT 时的“扬声器启用”位(不使用 PIT 时为扬声器“位置”)。
这是一个示意图(来自此 page )缺少手动驾驶部分:
PIT 通过端口 40h-43h 控制,每次除法器的两个字节时我们将使用模式 3(方波发生器)设置。
PIT 有一个运行频率约为 1.193180 MHz 的振荡器,分频器用于控制方波的周期。
不处理内部结构:在 PIT 振荡器的每个滴答处,加载的分频器都会递减。方波的周期等于 PIT 将分频器递减至零所需的时间。
产生声音只需使用所需的分配器对 PIT 进行编程并启用扬声器即可。
一段时间后,我们需要禁用它。
一个简单的方法是使用 int 1ch称为每秒 18.2 次。
通过在第一次播放声音时在变量中保存持续时间,在 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
将具有停止当前蜂鸣声并开始新的蜂鸣声的效果。
关于组装 8086 - DOSBOX - 如何发出蜂鸣声?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43996835/
在组装方面,我绝对是个初学者。我尝试找出以下内容的输出应该是什么: Jan dd 255,256 Feb dw 16, 17, 18, 19 Mar db 8, 9, 10, 11 Sub edi,
我正在用 AT&T 语法编写。这个循环应该检查大小写是否在 61-7A ASCII 范围内(这意味着是这个小字母) - 如果不是,则将其转换为空格“”。 change: movb (%esi)
mov eax, ptr_to_num1 ; little endian mov ebx, ptr_to_num2 ; little endian xor ecx, ecx xor edx, edx
我正在制作用于组装的 atoi 函数。 无论我尝试什么都行不通,我也不知道为什么。 有谁知道是什么问题? org 100h mov si, stri ;parameter call atoi
我正在使用 tasm 编写汇编程序。我的任务是编写一个程序,该程序将使用冒泡排序按字母顺序对输入的字符串进行排序。前任。如果你输入“hello”,它应该写成“ehello”。我已经写了请求输入字符串并
假设我的 GPU 包含一个名为 ADT7473 的芯片。 . 我有兴趣从该芯片接收有关我的卡温度的信息。 我的问题是,如何访问这个芯片?是使用 IN/OUT 指令完成的吗? 编辑: 我可能会添加芯片文
我需要在DOS下通过Assembly(intel)+C(c99)绘制QRCode。但看来我的内存太少了。我尝试将图像存储为位数组: image db 11111110b, ... 但无论如何我没有结果
这里有一个简短的问题。我有一个程序集被一些开发人员重复使用,其中包含各种功能,但在技术上分为代表功能逻辑 block 的各种命名空间。 现在,它提供的公共(public) namespace 越少越好
小端: mov eax,4 push dword 0x44434241 mov ebx,1 mov ecx,esp mov edx,4 int 0x80 add esp,4 我不明白为什么它打印 A
是否可以使用元编程技巧来允许在 assembly block 上使用 SFINAE?例如检测处理器上是否有类似“CPUID”的指令:(这不是有效的代码,但说明了我想要实现的目标) // This sh
我有以下形式的项目 - pom.xml - projectA - pom.xml - src/main/ - java - startupScript - projectB
在《微处理器的音乐应用》一书中,作者给出了以下算法,将两个 8 位有符号整数与 16 位有符号结果进行 4 象限相乘: 对原始操作数进行无符号乘法。然后为了更正结果,如果被乘数符号为负,则无符号单精度
我们有一个项目,我们正在 build 大量 Scalatra microservices通过使用 sbt-assembly 打包它们插件,然后使用 sbt-docker 创建 Docker 镜像插入。
所有使用布局的 assemble 用户都知道“{{> body }}”标记了任何使用布局的页面的内容插入点。但是是否可以定义多个插入点,而不是将所有内容都扔到 {{> body }} 所在的位置? 例
我刚开始学习汇编,我没有找到任何有用的内容。 我正在创建一个简单的程序来读取用户输入,基本上: section .bss opA: resw 1 opB: resw 1 section
我目前正在尝试在 bochs 中编译并运行一个简单的引导加载程序。目前,这是我的 bootloader.asm 文件: [BITS 16] [ORG 0x7C00] ;Where the code g
我正在组装一个“simon”游戏,我需要在按钮打开时发出蜂鸣声,蜂鸣声也应该彼此不同。谢谢 最佳答案 您可以使用speaker让您的设计保持简单。 扬声器可让您播放不同频率的方波,it can act
我无法通过任何文档找到问题的答案。 可靠集合通过云的多个节点共享,并且具有名称和持久性。 它们可以通过不同的应用程序共享还是特定于应用程序? 例如,两个不同的 MVC 应用程序对同一帐户托管的可靠字典
嗨,我有一个 SBT 构建文件,用于处理我们组织内的集成测试,测试本身可以工作,我可以单独运行单元和它测试。但是,当使用 sbt-assemble 打包应用程序时,我无法按顺序运行两个测试(unit+
我正在运行一些汇编代码,但我无法弄清楚一行代码的作用。代码是: leaq 0(,%rax,4), %rdx 我知道lea基本上是一种mov指令,但它只移动地址。因此,我们将某些内容的地址移动到%
我是一名优秀的程序员,十分优秀!