系统的简单注解 - 11 08_bs16.asm文件



该文件用于播放一段wav文件。

 

file_copy:将音乐文件拷贝到内存中。音乐文件被保存在硬盘逻辑扇区300的地方,长度为64K;

play_sound:播放该音乐文件;

install_0x25_interrupt:安装0x25号中断(DMA);

rtm_0x25_interrupt_handle:DMA中断处理过程;

write_dsp:向DSP写入命令;

read_dsp:从DSP读取状态 ;

;-------------------------------------------------------------------------------
file_copy:

	 mov eax, 300
     mov ebx, sound_file_address-44
	 mov ecx, 128
_file_cpy_loop:
     call read_hard_disk_0
	 inc eax
	 loop _file_cpy_loop

     ret	 

;-------------------------------------------------------------------------------
play_sound:	 
	 
	 pushad
	 
	 call file_copy
	 
     ;以下复位DSP芯片
     mov dx,0x226 
     mov al,1                         ;第一步,先写“1”到复位端口 
     out dx,al
    
     xor ax,ax
_@1:
     dec ax
     jnz _@1                          ;一个硬件要求的延时(至少3ms) 
    
     out dx,al                        ;第二步,写“0”到复位端口 

     call read_dsp
     cmp al,0xaa                      ;状态值0xaa表示初始化完成 
     jz _@4
    
     ret                              ;直接停机 

_@4:	 
     
	 ;对DMA控制器编程,设置其工作模式、缓冲区地址和传输长度
     mov dx,0x0a	               ;DMAC1的屏蔽寄存器
     mov al,00000_1_01B	       ;关闭主DMAC的1号通道 
     out dx,al                      
		
     ;计算缓冲区物理地址
     xor ax, ax                        ;bx:ax=缓冲区20位地址
     mov bx, 0x03	 

     xor al,al
     out 0x0c,al                      ;DMAC1高低触发器清零

     mov dx,0x02                      ;写通道1基址与当前地址寄存器
     out dx,al                        ;低8位DMA地址 
     mov al,ah
     out dx,al                        ;高8位DMA地址 

     mov dx,0x83                      ;写DMA通道 1 的页面寄存器
     mov al,bl
     out dx,al

     mov dx,0x03                      ;写通道1的基字计数与当前字计数器
     mov ax,65132                     ;数据块(当缓冲区用)的大小 
     dec ax                           ;DMA要求实际大小减一
     out dx,al                        ;缓冲区长度低8位
     mov al,ah
     out dx,al                        ;缓冲区长度高8位
       
     mov al,0101_1001b                ;设置DMAC1通道1工作方式:单字节传送/
     out 0x0b,al                      ;地址递增/自动预置/读传送/通道1

     mov dx,0x0a                      ;DMAC1屏蔽寄存器
     mov al,1                         ;允许通道1接受请求
     out dx,al

     mov al,0x40                      ;设置DSP采样率(播放)
     call write_dsp
     mov ax,65536-(256000000/(1*8000))
     xchg ah,al                       ;只使用结果的高8位 
     call write_dsp

     ;编程设置DSP的DMA传输模式和数据长度,以启动音频播放
     mov al,0x48
     call write_dsp
     mov ax,65132                     ;数据块(当缓冲区用)的大小
     shr ax,1                         ;长度设为DMA的一半
     dec ax 
     call write_dsp                   ;写低字节 
     xchg ah,al                      
     call write_dsp                   ;写高字节
  
     ;打开喇叭输出
     mov al,0xd1
     call write_dsp

     ;启动DSP的传输的播放
     mov al,0x1c
     call write_dsp
	 
	 popad

	 ret
	 
;-------------------------------------------------------------------------------
install_0x25_interrupt:                      ;安装0x25号中断(DMA)
	 
     cli	                              ;关中断
	 
     sidt [pidt]	                      ;取idt段地址
	 
     ;设置实时时钟中断处理过程
     mov eax, rtm_0x25_interrupt_handle   ;门代码在段内偏移地址
     mov bx, flat_4gb_code_seg_sel        ;门代码所在段的选择子
     mov cx, 0x8e00                       ;32位中断门,0特权级
     call make_gate_descriptor

     mov ebx, [pidt + 2]                  ;中断描述符表的线性地址
     mov [ebx + 0x25*8], eax              ;中断描述符低32位
     mov [ebx + 0x25*8 + 4], edx     	  ;中断描述符高32位
         
     lidt [pidt]                          ;重新加载中断描述符表寄存器IDTR	 
	 
     in al,0x21                           ;读8259主片的IMR寄存器
     and al,0xdf                          ;清除bit 5(DMA)
     out 0x21,al                          ;写回此寄存器
		 
     sti                                  ;开中断
	 
     ret		 
		 
;-------------------------------------------------------------------------------  
rtm_0x25_interrupt_handle:                    ;DMA中断处理过程
      pushad
      
      ;退出自动初始化模式
      ;mov al,0xda
      ;call write_dsp
      
      ;关闭扬声器
      ;mov al,0xd3
      ;call write_dsp
       
      mov dx,0x22f                     ;DSP中断应答
      in al,dx

      ;发送EOI命令到中断控制器(主片)
      mov al,0x20                      ;中断结束命令EOI
      out 0x20,al                      ;发给主片 
	  
      popad      
      iret		 

;------------------------------------------------------------------------------- 
write_dsp:
      push edx
      push eax
      
      mov dx,022ch
_@22c:
      in al,dx                        
      and al,1000_0000b	               ;监视22c端口的第7位,直到它变为0
      jnz _@22c

      pop eax
      out dx,al
      pop edx
      
      ret

;-------------------------------------------------------------------------------
read_dsp:
      push edx
      
      mov dx,22eh
_@22e:
      in al,dx                          
      and al,1000_0000b                ;监视22e端口的位7,直到它变成1
      jz _@22e
      mov dx,22ah
      in al,dx                         ;此时可以从22a端口读取数据
      
      pop edx
      
      ret
	  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值