⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pc4.asm

📁 PC计算机钢琴程序子程序: 包括以下资料 软件:提取音乐代码的软件工具(自己用VB写的) 资料:所有与按键和PC Sound有关资料 唱歌:包括歌曲有 聚萍、同一首歌、月亮代表我的心、美丽的神
💻 ASM
字号:
;/*-------------------------------------------------------------------------------------------*/
;数据段定义
data 	segment								;数据定义段
	assume		ds:data						;建立数据段寄存器寻址

msg_1   db	'<<---Welcome you to this OS.--->> $',0dh,0ah		;定义字节
msg_2	db	0dh,0ah,'In this OS. you can press below keys to enjoy:$'
msg_3	db	0dh,0ah,'Super Low:	q-w-e-r-t-y-u$'
msg_4	db	0dh,0ah,'      Low:	a-s-d-f-g-h-j$'
msg_5	db	0dh,0ah,'      Mid:	z-x-c-v-b-n-m$'
msg_6	db	0dh,0ah,'      Hig:	1-2-3-4-5-6-7$'
msg_7   db	0dh,0ah,'Anytime you can press ''Esc'' or ''Enter'' to exit.$'
msg_8	db	0dh,0ah,'What''s more, you can press ''p'' to play music!$'
msg_9	db	0dh,0ah,' $'

note_t	dw  	131,147,165,175,196,220,247		;超低音
	dw  	262,294,330,349,392,440,494		;低音
        dw  	523,587,659,698,784,880,988		;中音
        dw  	1046,1175,1318,1397,1568,1760,1975	;高音
	dw	0					;休止符0

;		'1','2','3','4','5','6','7'		;从低到高
key_t	db	'q','w','e','r','t','y','u'		;超低音				
	db	'a','s','d','f','g','h','j'		;低音
	db	'z','x','c','v','b','n','m'		;中音
	db	'1','2','3','4','5','6','7'		;高音
	db	'0'					;休止符0
			
music_n    db    '0','g','z','c','b','z','j','c','b','0','b','n','m','1','n','n','b','c','x'
           db    'z','z','z','c','x','z','z','z','x','c','x','z','h','x','c','x','0','g','c','b','c','x','z','b','j'
           db    'h','j','h','j','h','g','c','b','c','x','z','b','j','h','j','z','z','z','x','c','x','0','g'
           db    'z','c','b','z','j','c','b','b','n','m','1','n','n','b','b','c','x','z','z','z','c','x','z','z','z','c','x','x','h','j','z','x','z',0

music_d    db    4,  4,  8,  4,  8,  4,  8,  4,  8,  4,  4,  4,  8,  8,  4,  4, 16,  4,  4
           db    8,  4,  8,  4,  4,  8,  4,  8,  4,  4,  4,  4,  8,  4,  4, 32,  8,  8,  4,  4,  8,  4,  8,  8, 32
           db    4,  4,  8,  4,  8,  8, 32,  8,  8,  4,  8,  8, 32,  4,  4,  8,  4,  8,  4,  4, 32,  8,  8
           db    8,  4,  8,  4,  8,  4,  8,  4,  8,  4,  8,  4,  4,  4, 16,  4,  4,  8,  4,  8,  4,  4,  8,  4,  8,  4,  4,  8,  4,  8,  4,  4, 32

	
jiepai  db   	?		;节拍变量定义
speed	db	2		;播放速度控制
jiange	db	1		;音符间隔停顿时间

data	ends			;数据定义段结束
;/*-------------------------------------------------------------------------------------------*/



;/*-------------------------------------------------------------------------------------------*/
;代码段定义
code    segment				;代码定义段
        assume		cs:code		;建立代码段寄存器寻址
;/*-------------------------------------------------------------------------------------------*/



;/*-------------------------------------------------------------------------------------------*/
;字符显示
show	macro 		str		;宏定义,输入参数:字符串str
        lea		dx,str		;装入str的有效地址
        mov 		ah,09h		;调用中断21,09h显示字符串
        int 		21h	
        endm				;宏定义结束
;/*-------------------------------------------------------------------------------------------*/



;/*-------------------------------------------------------------------------------------------*/
;主函数
main	proc		far		;主函数过程定义
	mov 		ax,data		;取数据段地址
	mov 		ds,ax		;装载数据段寄存器ds,使之指向当前数据段
	show		msg_1		;调用宏,显示字符串
	show		msg_2
	show		msg_3
	show		msg_4
	show		msg_5
	show		msg_6
	show		msg_7
	show		msg_8
	show		msg_9
	mov		bx,0		;设定查表数组下标初值
	mov     	al,6
;/*-------------------------------------------------------------------------------------------*/




;/*-------------------------------------------------------------------------------------------*/
;按键扫描
key_scan:
	mov     	jiepai,6    	;初始化节拍
	mov		bx,0000h	;初始化指针
	
	mov		ah, 00h		;利用bios的16号中断,扫描键盘按键
	int		16h		;AL中返回按键的ASCII码,AH中返回按键的扫描码
	cmp		al, 0dh		;判断是否为Enter键
	jz		exit		;是回车键就退出

	cmp		al, 1bh		;判断是否为Esc键
	jz		exit		;是退出键就退出

	cmp		al, 'p'		;判断是否为p键
	jz		play		;是p键就play music
		
lookup:
	cmp		key_t[bx],al	;取出对应频率值
	je		next
	inc		bx		;指针+1			
	jmp		lookup
	
next:
	shl		bx,1		;指针×2,计算频率表指针
	mov		cx,note_t[bx]	;取得对应数组下标值的频率值
	call		beep		;调用固定频率子程序	
	jmp		key_scan	;否则继续扫描
;/*-------------------------------------------------------------------------------------------*/	




;/*-------------------------------------------------------------------------------------------*/
;音乐播放
play:	mov		bx,0

next3:	mov		al,music_n[bx]	;取出music频率值
    	push    	ax  
    	mov		al,music_d[bx]	;取出music节拍
    	mov     	jiepai,al
    	pop     	ax
	cmp		al, 0		;是否为音乐结束标志符
	je		key_scan	;是则退出play
	push		bx		;保存bx,bx为music频率指针

	

	mov		bx,0
look1:	cmp		key_t[bx],al	;查表取出对应频率值的指针bx
	je		next1		;找到就beep
	inc		bx		;指针+1	
	and		bx,0ffh		
	jmp		look1		;未找到则继续查找
	
next1:
	shl		bx,1		;指针×2,计算频率表指针
	mov		cx,note_t[bx]	;取得对应数组下标值的频率值
	cmp		cx,0
	je		next4
	call		beep		;调用固定频率子程序
	call		pause		;调用停顿时间
	pop		bx		;获得music指针
	inc		bx		;继续取得下一个音符		
	jmp		next3		

next4:	call		nobeep
	call		pause		;调用停顿时间
	pop		bx		;获得music指针
	inc		bx		;继续取得下一个音符
	jmp		next3
;/*-------------------------------------------------------------------------------------------*/



;/*-------------------------------------------------------------------------------------------*/
;退出
exit:
        mov 		ah,4ch		;调用中断21,4ch退出系统
        int 		21h
;/*-------------------------------------------------------------------------------------------*/



;/*-------------------------------------------------------------------------------------------*/
main	endp				;主函数过程结束
;/*-------------------------------------------------------------------------------------------*/



;/*-------------------------------------------------------------------------------------------*/
;固定频率响
beep    proc		near

	mov		dx,0012h
	mov		ax,34dch
	div		cx		;ax为所得分频值

	out		42h,al		;输出频率值,低8位
	mov		al,ah
	out		42h,al		;输出频率值,高8位
	
	call		spk_on		;开启蜂鸣器
	
	mov		ah,00h		;取时钟计数值
	int		1ah		
	mov		al,jiepai	;18.2次为1000ms, 2次约为100ms
	add		al,speed
	cbw                          	;al值转为16位ax
	add		ax,dx		;加上当前时钟计数值,得到计数终值
	mov		bx,ax		;计数终值置入bx
delay1:	mov		ah,00h
	int		1ah		;取时钟计数值
	cmp		bx,dx		;到终值吗?
	jnz		delay1		;未到,继续延时

	call		spk_off		;关闭蜂鸣器
	
	ret
beep    endp
;/*-------------------------------------------------------------------------------------------*/




;/*-------------------------------------------------------------------------------------------*/
;休止符延迟时间
nobeep  proc		near

	call		spk_off		;关闭蜂鸣器
	
	mov		ah,00h		;取时钟计数值
	int		1ah		
	mov		al,jiepai	;18.2次为1000ms, 2次约为100ms
	add		al,speed
	cbw                          	;al值转为16位ax
	add		ax,dx		;加上当前时钟计数值,得到计数终值
	mov		bx,ax		;计数终值置入bx
delay2:	mov		ah,00h
	int		1ah		;取时钟计数值
	cmp		bx,dx		;到终值吗?
	jnz		delay2		;未到,继续延时
	
	ret
nobeep  endp
;/*-------------------------------------------------------------------------------------------*/




;/*-------------------------------------------------------------------------------------------*/
;音符间隔停顿时间
pause   proc		near

	call		spk_off		;关闭蜂鸣器
	
	mov		ah,00h		;取时钟计数值
	int		1ah		
	mov		al,jiange	;18.2次为1000ms, 2次约为100ms
	cbw                          	;al值转为16位ax
	add		ax,dx		;加上当前时钟计数值,得到计数终值
	mov		bx,ax		;计数终值置入bx
delay3:	mov		ah,00h
	int		1ah		;取时钟计数值
	cmp		bx,dx		;到终值吗?
	jnz		delay3		;未到,继续延时
	
	ret
pause   endp
;/*-------------------------------------------------------------------------------------------*/



;/*-------------------------------------------------------------------------------------------*/
;开启蜂鸣器
spk_on  proc		near
	push		ax
	in		al,61h		
	or		al,03h
	out		61h,al
	pop		ax
	ret
spk_on  endp
;/*-------------------------------------------------------------------------------------------*/





;/*-------------------------------------------------------------------------------------------*/
;关闭蜂鸣器
spk_off proc		near
	push		ax
	in		al,61h		
	and		al,0fch
	out		61h,al
	pop		ax
	ret
spk_off endp
;/*-------------------------------------------------------------------------------------------*/




;/*-------------------------------------------------------------------------------------------*/
code	ends				;代码段结束
	end		main		;主程序结束
;/*-------------------------------------------------------------------------------------------*/



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -