67 lines
1.4 KiB
NASM
67 lines
1.4 KiB
NASM
; 实验九 - 声音程序
|
|
; 功能: 通过端口操作产生声音
|
|
; 模式: 文本模式 80x25 彩色
|
|
|
|
.MODEL SMALL
|
|
.DATA
|
|
TONE_DB 200, 400, 600, 800, 1000
|
|
COUNT DB 5
|
|
|
|
.CODE
|
|
.STARTUP
|
|
MOV AX, @DATA
|
|
MOV DS, AX
|
|
|
|
; 初始化8253定时器
|
|
; 设置计数器2用于扬声器控制
|
|
MOV AL, 10110110B ; 模式3, 二进制计数, 计数器2
|
|
OUT 43H, AL ; 写入控制字
|
|
|
|
; 演奏音阶
|
|
LEA SI, TONE_DB
|
|
MOV CL, [COUNT]
|
|
|
|
TONE_LOOP:
|
|
LODSB ; 读取音调频率
|
|
CBW ; 扩展为16位
|
|
|
|
; 写入计数初值 (频率 --> 计数器值)
|
|
; 计数器值 = 1193180 / 频率
|
|
MOV DX, 12H ; 1193180 的高位
|
|
MOV CX, 34DCH ; 1193180 的低位 (简化)
|
|
; 实际应用中需要更精确的计算
|
|
|
|
; 设置频率
|
|
OUT 42H, AL ; 先写低字节
|
|
MOV AL, AH
|
|
OUT 42H, AL ; 再写高字节
|
|
|
|
; 打开扬声器
|
|
IN AL, 61H ; 读取端口61H
|
|
OR AL, 00000011B ; 设置位0和位1
|
|
OUT 61H, AL ; 写入端口61H
|
|
|
|
; 延时
|
|
MOV CX, 0FFFFH
|
|
DELAY1:
|
|
LOOP DELAY1
|
|
|
|
; 关闭扬声器
|
|
IN AL, 61H
|
|
AND AL, 11111100B ; 清除位0和位1
|
|
OUT 61H, AL
|
|
|
|
; 音调之间短暂停顿
|
|
MOV CX, 0FFFFH
|
|
DELAY2:
|
|
LOOP DELAY2
|
|
|
|
DEC CL
|
|
JNZ TONE_LOOP
|
|
|
|
; 停止
|
|
MOV AH, 01H
|
|
INT 21H
|
|
|
|
.EXIT
|
|
END |