www.pudn.com > liuxingequhubian.rar > music.asm


dispmsg macro message				;用来调用显示字符串的宏 
		mov dx,offset message 
		mov ah,9 
		int 21h 
		endm 
 
data segment 
;音乐播放时,提示的字符 
msgdoing	db 0dh,0ah,0dh,0ah 
		db 0dh,0ah,'     Now,playing the pop music which you chose!Please enjoying...' 
		db 0dh,0ah,0dh,0ah,'$' 
 
;提示选择乐曲 
msgchoose  	db 0dh,0ah,'Input the number(1~3) to choose the music you want,input:','$' 
 
;提示输入字符错误 
msgerror   	db 0dh,0ah,0dh,0ah,0dh,0ah,'!!! sorry, you input a wrong number!!!',0dh,0ah 
		db 'please try to choose from 1 to 3 again!,input:','$' 
 
;以下是显示音乐菜单的字符串 
msgmenu  	db'************************************** ',0dh,0ah 
		db'*	The pop music menu is that:     * ',0dh,0ah 
		db'*  	                                * ',0dh,0ah 
 		db'*	1:dahai                         * ',0dh,0ah   	;张宇生《大海》	 
		db'*	2:dongfengpo                    * ',0dh,0ah	;周杰伦《东风破》 
		db'*	3:dashetou                      * ',0dh,0ah	;吴克群《大舌头》	 
		db'************************************** ',0dh,0ah,'$'	 
 
;以下对应为各乐曲的频率表和节拍时间表 
freq_dahai dw 196,220 
           dw 262,262,262,262,262,220,196 
           dw 262,262,262,262,294,262,220,262 
           dw 294,294,294,294,294,262,220 
           dw 294,294,294,294,330,294,330,392 
           dw 440,440,392,440,392,330 
           dw 294,294,330,294,262,220,196,220 
           dw 262,262,262,262,262,220 
           dw 262,196,220 
           dw 440,440,392,440,524,440 
           dw 392,330,294,262,220,196,220 
           dw 262,262,262,262,294,262 
           dw 262,330,392 
           dw 440,440,440,440,524,440 
           dw 392,392,392,440,392,330,294 
           dw 262,262,262,262,294 
           dw 330,330,294 
           dw 262,262,262,262,524,440 
           dw 392,392,392,440,392,330,392 
           dw 440,524,524,440,392 
           dw 392,330,392 
           dw 440,440,440,440,524,440 
           dw 392,392,392,440,392,330,294 
           dw 262,262,262,262,392 
           dw 330,330,294 
           dw 262,262,262,262,294,330 
           dw 392,392,330,392,330,392 
           dw 440 
           dw 9,9,196,660,294,294,262 
           dw 262,-1                            ;最后一个以“-1”控制结束 
 
time_dahai dw 400,400 
           dw 400,200,400,400,800,400,400 
           dw 400,200,400,200,200,800,400,400 
           dw 400,200,400,400,800,400,400 
           dw 400,200,400,200,200,800,400,400 
           dw 400,800,400,800,400,400 
           dw 400,200,200,400,400,800,400,400 
           dw 400,200,400,400,800,800 
           dw 1600,800,800 
           dw 400,800,400,800,400,400 
           dw 400,400,400,400,800,400,400 
           dw 400,800,400,800,400,200 
           dw 2400,400,400 
           dw 400,800,400,800,400,400 
           dw 400,800,200,200,800,400,400 
           dw 400,800,400,800,800 
           dw 2400,400,400 
           dw 400,800,400,800,400,400 
           dw 400,800,200,200,800,400,400 
           dw 800,400,800,400,200 
           dw 2400,400,400 
           dw 400,800,400,800,400,400 
           dw 400,800,200,200,800,400,400 
           dw 400,800,400,800,800 
           dw 2400,400,400 
           dw 400,800,400,800,400,400 
           dw 400,800,400,800,400,400 
           dw 3200 
           dw 800,400,400,400,400,400,400 
           dw 4000 
freq_dongfengpo dw 294,262,294,330,294,262,294,262,262,220,294 
                dw 294,262,294,330,294,262,294,262,262,220,196 
                dw 392,392,330,330,330,330,349,392,349,349 
                dw 294,294,330,294,262,220,262,440,440,440,392,392   
                dw 294,262,294,330,294,262,294,262,262,220,294 
                dw 294,220,262,294,262,294,330,392,392,330,392 
                dw 392,392,392,440,330,349,392,440,349 
                dw 294,294,262,330,294,262,220,294,262,294,262 
                dw 392,392,392,440,494,440,392,330,330,330,294,294 
                dw 392,392,392,330,294,294,262,294,262,294,330,330 
                dw 247,247,294,330,294,330,392,330,294,262,294,220 
                dw 262,262,294,330,294,330,392,440,392,392,330,330,330,330,294 
                dw 392,392,392,440,494,440,392,330,330,330,294,294 
                dw 392,392,392,330,294,294,262,294,262,294,330,330 
                dw 247,247,294,330,294,330,392,440,392,392,330,392,440,440,392,330,392,330,292 
                dw 294,294,262,330,294,262,220,294,262                                                                    
                dw -1 
time_dongfengpo dw 800,800,800,1600,800,800,800,800,800,800,1600 
                dw 800,800,800,1600,800,800,800,800,800,800,1600 
                dw 800,800,800,800,800,800,800,1600,800,1600 
                dw 800,800,800,800,1000,800,800,800,800,800,800,800 
                dw 800,800,880,1600,800,800,800,800,800,800,1000 
                dw 800,800,800,1600,800,400,800,800,800,800,1600 
                dw 800,800,800,1600,800,800,1600,800,800,1000 
                dw 800,800,800,800,800,800,800,800,800,800,2400 
                dw 800,800,800,1600,200,800,600,800,800,800,800,1600 
                dw 800,800,800,800,800,800,600,800,800,800,800,1600 
                dw 800,800,800,800,800,800,600,800,800,800,800,1600 
                dw 800,800,800,800,800,800,600,800,800,800,800,800,800,800,800 
                dw 800,800,800,1600,200,800,600,800,800,800,800,1600 
                dw 800,800,800,800,800,800,600,800,800,800,800,1600 
                dw 800,800,800,800,800,800,600,800,800,800,800,1600,800,800,800,1600,400,800,600 
                dw 800,800,800,800,800,800,600,800,4000 
 
freq_dashetou dw 524,524,524,524,494,524,588,524 
              dw 524,524,524,524,494,524,494,392 
              dw 524,524,524,524,494,524,588,524 
              dw 330,330,294,294,262,330,300,262 
              dw 524,524,524,524,494,524,588,524 
              dw 524,524,524,524,494,524,494,392 
              dw 524,524,524,524,494,524,588,524 
              dw 330,330,294,294,262,330,300,262   
              dw -1     
time_dashetou dw 500,500,500,500,1000,500,500,500 
              dw 500,500,500,500,1000,500,500,500 
              dw 500,500,500,500,1000,500,500,500 
              dw 500,500,500,250,250,500,500,1000 
              dw 500,500,500,500,1000,500,500,500 
              dw 500,500,500,500,1000,500,500,500 
              dw 500,500,500,500,1000,500,500,500 
              dw 500,500,500,250,250,500,500,1000            
 
table dw music1,music2,music3		;取得各个标号的偏移地址 
data ends 
 
;主程序 
code segment 
assume cs:code,ds:data 
begin:mov ax,data 
      mov ds,ax 
next: dispmsg msgmenu			 
      dispmsg msgchoose		;提示菜单及输入数字 
 
inputbegin:mov ah,01h             
           int 21h 
           cmp al,'q'           ;输入q则退出 
           je exit 
           cmp al,'1'           ;比较数字<1?    
           jb doagain 
           cmp al,'4'           ;比较数字>4? 
           ja doagain 
           and ax,000fh		;将ASCII码转换成数字,以便后面指向table表里对应的地址 
	   dec ax		;减1,对应地址 
	   shl ax,1		;相当于ax*2,因为table里的相邻偏移地址是2 
	   mov bx,ax			 
	   jmp table[bx]	;(段内)间接转移:IP<--[table+bx]跳到table里面对应的程序段 
exit: mov ah,4ch 
      int 21h 
 
;***************输入错误时处理的程序[提示:再次输入]******************** 
doagain:dispmsg msgerror 
	jmp 	inputbegin              
 
;**********************以下对应为各乐曲的处理程序************************ 
music1:dispmsg msgdoing 
       mov si,offset freq_dahai 
       mov di,offset time_dahai 
m1:    mov cx,[si] 
       cmp cx,-1 
       je next 
       mov bx,[di] 
       call gensound 
       add si,2 
       add di,2 
       jmp m1 
 
music2:dispmsg msgdoing 
       mov si,offset freq_dongfengpo 
       mov di,offset time_dongfengpo 
m2:    mov cx,[si] 
       cmp cx,-1 
       je next 
       mov bx,[di] 
       call gensound 
       add si,2 
       add di,2 
       jmp m2 
 
music3:dispmsg msgdoing 
       mov si,offset freq_dashetou 
       mov di,offset time_dashetou 
m3:    mov cx,[si] 
       cmp cx,-1 
       je xx 
       jmp xx1 
xx:    jmp next 
xx1:   mov bx,[di] 
       call gensound 
       add si,2 
       add di,2 
       jmp m3 
 
;***********************音乐处理子程序************************* 
gensound proc near 
       push dx 
       mov al,0b6h             ;向计数器写控制字 
       out 43h,al              ;方式3、双字节写和二进制计数方式写到控制口 
       mov dx,08h              ;设置被除数 
       mov ax,3208h 
       div cx                  ;其商为预置值 
       out 42h,al              ;先送LSB   
       mov al,ah 
       out 42h,al              ;后送MSB 
       in al,61h               ;读端口原值 
       mov ah,al 
       or al,3 
       out 61h,al              ;接通扬声器 
l2:    push dx 
       push ax 
       mov dx,8h 
       mov ax,0f05h 
s1:    sub ax,1 
       sbb dx,0 
       jnz s1 
       pop ax 
       pop dx 
       dec bx 
       jnz l2 
   
  mov al,ah                   ;写回61h端口值,关闭扬声器 
  out 61h,al 
  pop dx 
  ret 
gensound endp 
  code ends 
  end begin