汇编源代码之MAKE SOUNDS(发声)

INTRODUCTION

This code example provides a set of keyboard routines to control sound output while waiting for a user to enter a keyboard character. The advantage to this method is that a main routine can call these sound routines to play a sound sequence, and the sound routines will return control back to the main routine whenever the user enters keyboard data so that the main routine can continue computing while the sound plays in the background. The code example has two different code entry points for getting keyboard data. One code entry point is a standard get_keyinput call which will wait for a key and update the sound data until a key code is found. The other code entry point is the get_keyinput_to call, which will wait a set amount of time for a key code and if none is found, return with a no key code found condition. The calling routine puts a timeout counter value in register AX on entry. The counter value is based on the system clock which ticks at 18.2 times per second. The entry point start_table_sound is used to begin a background sound sequence. On entry, the register BX indexes a table of sound data. The table has a format of four byte entries and is terminated by a data word of zero. The four bytes are used as two words: the first is a duration count and the second is a tone value. There are two code entry points for turning the background sound off and on. There is also a utility to flush out the keyboard buffer that can be executed with a call to flush_keyboard.

;Set of keyboard routines with sound outputs
.MODEL small
.STACK 500
.DATA
 ;define table for sound output
;sample_sounds   dw  8,45000  ;long low sound
;       dw  2,2000     ;short high sound
;       dw  0       ;end of sample sound table
sound_table  dw  0
sound_time_m  dw  0
sound_time_l  dw  0
sound_flag   db  0
sound_on_flag db  0,0
key_time_out_m dw  0
key_time_out_l dw  0
.CODE
;************ ^^^^^^^^^^ *************
;### code entry point #####
get_keyinput  proc near
;this routine checks for keyboard data in BIOS buffer
; and returns with data if there
;else it updates sound output data and loops to check for
; keyboard data again until keyboard data found
;on exit AX has keyboard data
   public  get_keyinput
   push bx
   push cx
   push dx
get_keyinput_loop:
     mov ah,1  ;set AH for scan
     int 16H  ;BIOS Call
      ;branch if no keyboard data
     jz  sound_update
     mov ah,0  ;set AH for get key
     int 16H  ;BIOS Call
   pop dx
   pop cx
   pop bx
   ret
;******* -------- *******
sound_update:
   cmp sound_flag,0    ;check for sound on????
   jz  get_keyinput_loop  ;branch out if sound off
   mov cx,sound_time_m   ;else check for sound update
   mov ax,sound_time_l
   call test_current_time  ;is it time for update ??
   jc  get_keyinput_loop  ;branch if not time
   mov bx,sound_table
   mov ax,[bx]       ;get next sound update value
   or  ax,ax        ;?? end of sound ??
   jz  turn_sound_off   ;branch if end sound
   call get_time_plus_ax  ;reset sound duration
   mov sound_time_m,cx
   mov sound_time_l,ax
   inc bx
   inc bx
   mov ax,[bx]
   inc bx
   inc bx
   mov sound_table,bx
   call sound_out_ax    ;go set sound frequency
   jmp get_keyinput_loop ;branch to keyboard loop
turn_sound_off:
   call sound_off
   mov sound_flag,0
   jmp get_keyinput_loop ;branch to keyboard loop
get_keyinput  endp
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;************ ########## *************
;### code entry point #####
get_keyinput_to   proc near
;get keyboard data with timeout if no data available
;on entry AX has time duration in 18 ticks per second
;on exit if carry clear then AX has keyboard data
   public  get_keyinput_to
   push bx
   push cx
   push dx
   call get_time_plus_ax   ;add duration to current time
   mov key_time_out_m,cx  ;set timeout value
   mov key_time_out_l,ax
get_keyinput_to_loop:
   mov ah,1        ;ready to scan keyboard data
   int 16H         ;BIOS Call
   jz  sound_update_to   ;branch if no keyboard data
   mov ah,0        ;ready to get key data
   int 16H          ;BIOS Call
   pop dx
   pop cx
   pop bx
   clc            ;set keyboard data flag
   ret
get_keyinput_to_1:
   mov cx,key_time_out_m   ;check for timeout
   mov ax,key_time_out_l
   call test_current_time
   jc  get_keyinput_to_loop ;branch if no timeout
   xor ax,ax         ;else timeout return condition
   pop dx
   pop cx
   pop bx
   stc            ;set no keyboard data flag
   ret
; ******** %%%%%%% ********
sound_update_to:
   cmp sound_flag,0    ;check for sound on????
   jz  get_keyinput_to_1  ;branch if sound off
   mov cx,sound_time_m   ;else check for sound update
   mov ax,sound_time_l
   call test_current_time
   jc  get_keyinput_to_1  ;branch if not ready for update
   mov bx,sound_table
   mov ax,[bx]
   or  ax,ax        ;test for end of table
   jz  turn_sound_off_to  ;branch if end of table data
   call get_time_plus_ax
   mov sound_time_m,cx
   mov sound_time_l,ax
   inc bx
   inc bx
   mov ax,[bx]
   inc bx
   inc bx
   mov sound_table,bx
   call sound_out_ax
   jmp get_keyinput_to_1
turn_sound_off_to:
   call sound_off
   mov sound_flag,0
   jmp get_keyinput_to_1
get_keyinput_to   endp
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;************ @@@@@@@@@@ ************
;### code entry point #####
start_table_sound  proc near
;subroutine to start background sound output
;on entry BX indexes sound data table
   public  start_table_sound
   push ax
   push bx
   mov ax,[bx]
   call get_time_plus_ax
   mov sound_time_m,cx
   mov sound_time_l,ax
   inc bx
   inc bx
   mov ax,[bx]
   inc bx
   inc bx
   mov sound_table,bx
   call sound_out_ax
   mov sound_flag,0FFH
   pop bx
   pop ax
   ret
start_table_sound  endp
;************ ========== *************
;### code entry point #####
flush_keyboard proc near
 ;utility to flush contents of keyboard buffer
   public  flush_keyboard
   mov ah,1
   int 16H    ;BIOS Call ;scan for keyboard data
   jz  flush_keyboard_x   ;branch if no keyboard data
   mov ah,0         ;else get keyboard data
   int 16H    ;BIOS Call
   jmp flush_keyboard
flush_keyboard_x:
   ret
flush_keyboard endp
;************* ----------- **************
sound_out_ax  proc near
 ;set sound out frequency to data value in AX
   push ax
   push ax
   cmp sound_on_flag,0
   jne sound_out_1
   in  al,61H     ;input port 61h
   or  al,3
   out 61H,al     ;output port 61h
sound_out_1:
   mov al,0B6H
   out 43H,al     ;output port 43h
   pop ax
   out 42H,al     ;output port 42h
   xchg al,ah
   out 42H,al     ;output port 42h
   mov sound_on_flag,0FFH
   pop ax
   ret
sound_out_ax  endp
;*********** $$$$$$$$$$ ************
;###### code entry point #######
sound_off proc near
  ;turn sound port off
   public  sound_off
   push ax
   cmp sound_on_flag,0
   je  sound_off_exit
   in  al,61H     ;input port 61h
   and al,0FCH
   out 61H,al     ;output port 61h
   mov sound_on_flag,0
sound_off_exit:
   pop ax
   ret
sound_off endp
;************** %%%%%%%%%% ***************
;with all CX:AX time values, CX is most significant
; and AX is least significant
get_current_time  proc near
;on exit CX:AX has 32 bit day clock value
; in 18.2 ticks per second
   push dx
     xor ax,ax   ;set AH to zero
     int 1AH    ;BIOS Call get time
     mov ax,dx
   pop dx
   ret
get_current_time  endp
;****************************
get_time_plus_ax  proc near
;on entry AX has 16 bit value to add to current clock time
;on exit CX:AX has new 32 bit clock value
   push dx
   push ax
   xor ax,ax
   int 1AH      ;BIOS Call
   pop ax
   add ax,dx
   adc cx,0
   pop dx
   ret
get_time_plus_ax  endp
;************ ######## ************
test_current_time  proc near
;on entry CX:AX has time value
; to be subtracted from the current time
;on exit if carry set then current time
; is less than CX:AX time
   push dx
   push cx
   push ax
   xor ax,ax
   int 1AH      ;BIOS Call
   cmp dx,18
   jb  test_current_time_2
test_current_time_1:
   pop ax
   sub dx,ax
   pop dx
   sbb cx,dx
   mov cx,dx
   pop dx
   ret
test_current_time_2:
   or  cx,cx
   jnz test_current_time_1
   pop ax   ;this is fix code for midnight factor
   pop dx
   pop dx
   clc     ;clear carry condition
   ret
test_current_time  endp
;*****************************************
   end

时间: 2025-01-21 16:45:10

汇编源代码之MAKE SOUNDS(发声)的相关文章

汇编源代码之获得操作系统版本

dos下可以调用DOS中断服务程序, WINDOWS下可以调用 API 函数GetVersionEx() 这是我测试PE格式的STUB的源代码, 可以在DOS和WINDOWS下运行,其功能是报告当前OS信息. ; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ; FileName: os_type.asm ; function: Reports current operation system type ; Author : Pu

汇编源代码之汇编语言制作的光带菜单及源程序(1.0)

这个是我上大二的时候的汇编语言课程设计.自己做得很满意.现在拿出来,给大家看看.我对部分代码又从新做了调整.编译后大小比原来大了一点,不过速度上去了.其实就是一个图形接口.你只要在中间加上自己的实用功能,就可以直接用了.代码我都有注释,读起来应该不会有什么问题.当然,汇编的代码本身就很难读.所以有什么不是很好懂的地方,可以直接同我联系. 我还给同学做过一个C语言版的光带菜单,不过很可惜的是自己做得不是很满意,就把程序给删掉了.大家也就看不到了 本程序用 tasm 进行编译,tlink 进行连接.

汇编源代码之一个旋转的3D箱子(动画)

;本程序由国外的Vulture大哥编写,并公布了源码,这个是他95年的一个作品,可以说是在当时是非常成功的! ;这个程序是巧妙的利用了坐标的不断变化,从而实现了由星星构成的箱子3D转动! ;为了尊重版权,本人未对源码注释进行翻译,这样做也可以让国内的汇编爱好者自己琢磨国外的汇编编程的思维! ;编译方法: 1 tasm 3d.asm ; 2 tlink 3d.obj ; 3 exe2bin 3d.exe 3d.com ;本程序是站长精心收集的一个很经典的3D小动画. 站长的x86汇编小站:http

汇编源代码之简单密码输入

title***简单密码输入 by lluct***datasegment ;定义数据段input db 100 dup (?);定义输入的字符串,字符串必须用db定义,长度为100个字节cmpare db '5201314','$';定义密码msg1 db 'PASSWORD RIGHT!','$';定义输入密码正确后显示出来的信息msg2 db 'PASSWORD ERROR!','$';定义输入密码错误后显示出来的信息headmsg db 'ENTER YOUR PASSWORD:','$

汇编源代码之读寄存器内容

我的环境是WINXP+MASM5.0通过编译生成可执行文件,双击,提示写入文件成功,按任意键推出. 在程序的同一目录下的TEMP.TXT中已经写入了: ABCD 4645 4F5B FFFF 四行用来测试而显示送入寄存器的值. 以下是完整的代码, MovToVar Macro m_Reg,Asc_AX mov bx,m_Reg call ConvertToAsc lea si,CAscii lea di,Asc_AX mov cx,4d rep movsb EndM data segment m

汇编源代码之一个有趣的打字游戏

;--------------------------------------------------------------------------------;此模板是纯DOS程序代码,需要MASM5.0,编译时请使用"编译 -> DOS"方式.;--------------------------------------------------------------------------------Init_game macro op1,op2,op3,op4,op5,

汇编源代码之硬盘保护锁

我在前一段时间写了一个硬盘锁,拿出来和大家交流交流,同时有个问题,希望大家能帮我想想. 首先,大略介绍一下我的程序,我是用汇编写成,程序有2个文件:hdlock.exe hdlock.dat ,其中hdlock.dat是我写的用于装入硬盘0柱0道1扇的硬盘锁,hdlock.exe实现 (1)把hdlock.dat装入硬盘0柱0道1扇并设置硬盘锁的密码,(2)修改密码,(3)卸载硬盘锁 在此,先介绍一下 hdlock.dat,因为硬盘锁本身受空间限制,必须严格控制在1bdH字节内,(知道为什么吗?

汇编源代码之图形显示方式屏幕的保存和恢复

在程序中常常要暂时的保存图形显示方式屏幕上的内容,然后把自己的信息输出到屏幕上,结束后再恢复原来的屏幕内容,特别在内存驻留程序弹出一个窗口时更要用到,但是图形方式下显示缓冲区的容量巨大,在常用的 80 x 25 文本方式下,显示缓冲区仅大小仅为 80 x 25 x 2 = 4000 字节,而在模式 13H 320 x 200 x 256 色时为 320 x 200 = 64000 字节,现在常用的高彩色.真彩色下如 800 x 600 x 65535 色时为 800 x 600 x 2 = 96

汇编源代码之CIH文件型病毒检测消除程序

;本程序在Tasm下编译通过;CIH文件型病毒检测消除程序GOFIRST MACROXOR CX,CXXOR DX,DXMOV AX,4200HINT 21H ;文件指针指到文件首ENDMALTERLINE MACROMOV DL,0DHMOV AH,02HINT 21H ;回车MOV DL,0AHMOV AH,02HINT 21H ;换行ENDMCOPYHANDLE MACROPUSH BXMOV AH,45HINT 21H ;复制文件把柄MOV BX,AXMOV AH,3EHINT 21H