首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

組合語言聲音程式設計:鍵盤驅動背景音效完整實作

     編輯:組合語言

前言

在即時系統與遊戲開發中,如何在等待使用者輸入的同時播放背景音效,是一個經典課題。本文深度解析一套完整的組合語言聲音常式庫,實現「鍵盤輪詢與音效更新並行」的非阻塞架構,適用於 DOS 保護模式與即時應用開發。

核心架構設計

雙模式鍵盤輸入入口點

  • get_keyinput:阻塞式等待按鍵,期間持續更新背景音效,直到有鍵盤資料才返回(AX 含鍵碼)。
  • get_keyinput_to:帶逾時的非阻塞版本,入口 AX 為逾時計數(系統時鐘 18.2Hz),逾時返回 CF=1、AX=0;有鍵則 CF=0、AX 為鍵碼。

背景音效資料結構

音效表位於 sound_table,每筆 4 位元組(兩字):

DW  duration_count   ; 持續時間(時鐘節拍數)
DW  tone_value       ; 頻率值
; 以 DW 0 結束

範例表(註解掉):8, 45000(長低音)、2, 2000(短高音)。

關鍵模組詳細解析

1. 音效更新核心 sound_update

兩個入口點共用此邏輯:檢查 sound_flag、比對目前時間(CX:AX)與 sound_time_m:l,到期則讀取下一筆音效資料,呼叫 sound_out_ax 設定頻率,並重設下次觸發時間。表尾觸發 turn_sound_off。

2. 精確計時工具組

  • get_current_time:INT 1Ah AH=0 取得 32 位元系統時間(CX:DX,18.2Hz)。
  • get_time_plus_ax:目前時間 + AX → 新 CX:AX,處理進位。
  • test_current_time:目前時間 ≥ 目標時間?CF=0:是;CF=1:否。含午夜跨越修正邏輯。

3. 硬體喇叭控制(8253/8254 定時器 + 61h 埠)

sound_out_ax:
    ; AX = 頻率值
    in  al, 61h        ; 讀取喇叭控制埠
    or  al, 3          ; 開啟喇叭閘道 (bit 0,1)
    out 61h, al
    mov al, 0B6h       ; 8253 模式 3,二進位計數
    out 43h, al
    out 42h, al        ; 低位元組
    xchg al, ah
    out 42h, al        ; 高位元組
    mov sound_on_flag, 0FFh
    ret

sound_off:
    in  al, 61h
    and al, 0FCh       ; 關閉喇叭閘道
    out 61h, al
    mov sound_on_flag, 0
    ret

4. 輔助工具

  • start_table_sound:以 BX 指向音效表啟動背景播放,設定 sound_flag=0FFh。
  • flush_keyboard:清空 BIOS 鍵盤緩衝區(INT 16h AH=1/0 迴圈)。

整合應用範例

; 主程式片段
mov bx, offset my_sound_table
call start_table_sound

main_loop:
    call get_keyinput_to   ; 帶 5 秒逾時
    jc timeout_handler
    ; 處理鍵盤輸入 AL
    jmp main_loop

技術亮點總結

  1. 非阻塞並行:鍵盤掃描與音效更新交織在同一迴圈,無需中斷或多執行緒。
  2. 精確計時:32 位元時間運算搭配進位處理,支援長音效序列與午夜跨越。
  3. 模組化介面:6 個公開入口點(PUBLIC),易於連結至 C/其他模組。
  4. 資源保護:暫存器完整保存/恢復(PUSH/POP BX, CX, DX),符合呼叫慣例。

適用場景與延伸

  • DOS 遊戲背景音樂引擎核心
  • 嵌入式系統提示音與按鍵音同步播放
  • 教學示範:即時系統輪詢架構設計

此程式碼展示了組合語言在硬體控制與即時調度上的極致效能與彈性,是系統程式設計師必讀的經典範例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved