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

📄 mcd.asm

📁 只要你想听CD,它在任何时候(DOS下,游戏下都可以)用鼠标激活,鼠标控制,为你播放.并提供了选曲和暂停功能,这为光驱上无直接播放建的朋友提供了莫大的方便.该程序思路巧妙,利用INT 33H的现有鼠标
💻 ASM
字号:
;mcd.asm
.286
code segment
     assume cs:code,ds:code
     org 100h
start:
jmp init_cd              ;到初始化
cd_command db 32 dup(0)  ;CD-AUDIO 控制区
cd_state db 32 dup(0)    ;CD-AUDIO 状态区
max_track db 0,0         ;CD最大道
min_track db 0,0         ;CD最小道
lead_track dw 0
track dw ?               
track_buff db 40*4 dup(?)   ;CD音道数据区(预定为40个)
int33_off dw ?         ;原鼠标中断向量
int33_seg dw ?
user_dx dw ?           ;用户鼠标事件向量
user_es dw ?
mark db 0
ctrl db 0              ;CD控制方式 
next equ 1             ;前进
back equ 0             ;到退
stop equ 2             ;停止
cd_rom_driver dw ?     ;CD驱动器号
red_max_h dw ?
red_max_l dw ?
cd_int macro   ;控制CD-AUDIO的宏
mov ax,1510h
mov cx,cd_rom_driver
int 2fh
endm

my:                ;本程序的鼠标事件 MY
pushf
cmp bx,7       ;是否三键同时按下
jnz ttt
mov cs:ctrl,stop   ;停止
jmp ll
ttt:
cmp bx,3       ;是否两键同时按下
jnz q
cmp dx,1      ;鼠标在最上
jnb other
mov cs:ctrl,stop   ;停止
jmp ll
other:
cmp cx,599    ;鼠标在最右
jb qqq
mov cs:ctrl,next ;前进
jmp ll

qqq:
cmp cx,1
jae q
mov cs:ctrl,back  ;鼠标在最左,倒退
ll:
pusha
push ds
push es

push cs
pop ds
push cs
pop es

call mediachg    ;是否更换CD
cmp al,0ffh
jnz che
call init        ;更换CD后的初始化
che:
call check       ;CD状态检查
cmp cs:ctrl,next
jz ff
cmp cs:ctrl,back
jz rew

ff:                ;前进
cmp al,max_track   ;是超过最大音轨
jb goo
mov al,0           ;如超过,由第一音轨开始
goo:
inc al             ;音轨加一
jmp okk

rew:                ;倒退
cmp al,1            ;是否小于最小音轨
ja dy
mov al,max_track    ;如小于,由最大音轨开始
jmp okk
dy:
dec al              ;音轨减一

okk:
mov byte ptr cs:track,al
call pause          ;暂停
cmp cs:ctrl,stop
jz exit
call play           ;播放
exit:
pop es
pop ds
popa

q:
cmp cs:mark,1       ;用户事件是否有效
jnz qq
popf
jmp dword ptr cs:user_dx;转向(模拟)用户鼠标事件
qq:
popf
retf                ;MY 鼠标事件返回

new_33 proc near   ;新的鼠标中断
cmp ax,8888h
jnz l005
mov ax,'zd'        ;是否已驻留
iret               ;中断返回

l005:
cmp ax,000ch
jz l_000           ;设置鼠标事件,转l_000
cmp ax,0
jz mre
cmp ax,0021h
jnz l001           ;鼠标初始化

mre:
mov cs:mark,0
pushf
call dword ptr cs:int33_off ;调用原鼠标中断初始化
pusha
push es
mov ax,cs
mov es,ax
mov ax,000ch              ;0Ch号功能,设置鼠标事件
mov cx,00001010b          
mov dx,offset my          ;指向 MY
pushf
call dword ptr cs:int33_off;设置本程序鼠标事件 MY
pop es
popa
iret                        ;中断返回
l001:
jmp dword ptr cs:int33_off  ;调用其它鼠标功能

l_000:                      ;
mov cs:user_dx,dx
mov cs:user_es,es           ;保存用户鼠标事件向量
push es
push dx
push cs
pop es
mov dx,offset my           ;指向 MY
mov cs:mark,1              ;设置标志,表示是用户事件
pushf
call dword ptr cs:int33_off;设置用户鼠标事件,
                           ;实质是指向本程序事件MY
pop dx
pop es
iret                        ;中断返回
new_33 endp

init proc near             ;初始化,读取CD-AUDIO信息
mov track,1
mov di,offset track_buff
mov byte ptr cd_command[0],1ah
mov byte ptr cd_command[1],0
mov byte ptr cd_command[2],03
mov byte ptr cd_command[13],00     
mov word ptr cd_command[20],0000h 
mov word ptr cd_command[24],0000h
mov word ptr cd_command[22],0000h
mov word ptr cd_command[16],es
mov word ptr cd_command[14],offset cd_state 
mov word ptr cd_command[18],0007h
mov byte ptr cd_state[0],0ah
mov ax,ds                   
mov es,ax                   
mov bx,offset cd_command    
cd_int                            ;调用CD服务程序
mov al,byte ptr cd_state[1]
mov min_track,al                 ;最小音轨号
mov al,byte ptr cd_state[2]
mov max_track,al                 ;最大音轨号
mov al,byte ptr cd_state[5]
xor ah,ah
xor dx,dx
xor cx,cx
mov bx,4500                      ;每分钟扇区数
call szd
push dx                      
push ax                      
mov al,byte ptr cd_state[4]
xor ah,ah                   
xor dx,dx
xor cx,cx                   
mov bx,75                         ;每秒钟扇区数
call szd                    
pop bx                      
pop cx                      
add bx,ax                   
adc cx,dx                   
mov al,byte ptr cd_state[3] 
xor ah,ah
xor dx,dx
add bx,ax                   
adc cx,dx
add bx,0ff6ah               
adc cx,-01                  
mov red_max_h,cx
mov red_max_l,bx                 ;保存最大扇区数
test word ptr cd_command[3],8000h 
je bza                  
mov ax,0ffffh                  ;出错AX=FFFF
jmp quit_2                  
bza:         
mov ax,ds                   
xor dx,dx                   
mov word ptr cd_command[16],es 
mov word ptr cd_command[14],offset cd_state
mov word ptr cd_command[18],0007h
mov byte ptr cd_state[0],0bh      
mov si,word ptr min_track     
jmp bzb
bzc:         
mov ax,si                  
mov byte ptr cd_state[1],al    ;al为音轨号 
mov ax,ds                   
mov es,ax                   
mov ax,offset cd_command
mov bx,ax                   
cd_int
mov al,byte ptr cd_state[4] 
xor ah,ah                   
xor dx,dx                   
xor cx,cx                   
mov bx,4500
call szd
push dx                      
push ax                      
mov al,byte ptr cd_state[3] 
xor ah,ah
xor dx,dx
xor cx,cx                   
mov bx,75
call szd                    
pop bx
pop cx                      
add bx,ax                   
adc cx,dx                   
mov al,byte ptr cd_state[2] 
xor ah,ah                   
xor dx,dx                   
add bx,ax
adc cx,dx
add bx,0ff6ah               
adc cx,-01                  
mov word ptr [di+2],cx        
mov word ptr [di+0],bx
add di,4
test word ptr cd_command[3],8000h 
je bzd
mov ax,0ffffh              ;出错
jmp quit_2
bzd:         
inc si                     ;音轨号加1  
bzb:         
cmp si,word ptr max_track  ;是否超过最大音轨号
ja quit_2                  
jmp bzc                  
quit_2:ret
init endp

szd proc near               ;乘法计算
push si    
xchg ax,si
xchg ax,dx 
test ax,ax
je bzz
mul bx    
bzz:         
xchg ax,cx 
test ax,ax
je bzx
mul si    
add cx,ax  
bzx:         
xchg ax,si  
mul bx     
add dx,cx
pop si     
ret
szd endp

play proc near              ;播放CD
mov byte ptr cd_command[0],16h
mov byte ptr cd_command[1],0
mov byte ptr cd_command[2],84h     
mov byte ptr cd_command[4],0
mov byte ptr cd_command[13],00
mov di,offset track_buff
mov bx,track
dec bx
shl bx,1
shl bx,1
mov dx,red_max_h
mov ax,red_max_l
sbb dx,[di+bx+2]
sub ax,[di+bx+0]
mov word ptr cd_command[20],dx ;要播放的扇区数
mov word ptr cd_command[18],ax 
mov dx,word ptr [di+bx+2]
mov ax,word ptr [di+bx+0]
mov word ptr cd_command[16],dx
mov word ptr cd_command[14],ax ;起始扇区数
mov bx,offset cd_command
cd_int        
test word ptr cd_command[3],8000h 
jne err_p                   ;出错
xor ax,ax                   
jmp quit_1
err_p:mov ax,0ffffh         ;出错
quit_1:ret
play endp

pause proc near             ;暂停
mov byte ptr cd_command[0],16h      
mov al,7                    
mov byte ptr cd_command[1],al
mov byte ptr cd_command[2],85h
mov bx,offset cd_command
cd_int
ret
pause endp

check proc near             ;检查CD状态
mov byte ptr cd_command[0],1ah      
mov byte ptr cd_command[1],0      
mov byte ptr cd_command[2],3h      
mov byte ptr cd_command[13],0
mov word ptr cd_command[20],0
mov word ptr cd_command[24],0
mov word ptr cd_command[18],0bh
mov cd_command[16],ds
mov word ptr cd_command[14],offset cd_state
mov byte ptr cd_state[0],0ch
mov bx,offset cd_command
cd_int
xor ax,ax
mov al,cd_state[2]
mov bl,al                        ;BCD到16进制转换
mov cl,4
and bl,11110000b
jz quit
shr bl,cl
and al,00001111b
crep:
add al,10
dec bl
jnz crep
quit:ret                    ;返回当前音轨号
check endp

mediachg proc near
mov     byte ptr cd_command[0],1ah
mov     byte ptr cd_command[1],0
mov     byte ptr cd_command[2],03
mov     word ptr cd_command[14],0000h
mov     word ptr cd_command[16],0000h
mov     word ptr cd_command[18],0000h
mov     word ptr cd_command[16],es
mov     word ptr cd_command[14],offset cd_state
mov     word ptr cd_command[18],0002h
mov     byte ptr cd_state[0],09h
mov     ax,ds
mov     es,ax
mov     bx,offset cd_command
cd_int                         ;调用CD服务程序
mov al,cd_state[1]
ret                           ;返回al=0ffH,则更换过CD片
mediachg endp

init_cd:
mov ax,8888h
int 33h
cmp ax,'zd'
jnz l004                  ;驻留检查
mov dx,offset mess
mov ah,9
int 21h
jmp _quit                 ;已驻留,则退出
l004:
mov ax,0                  ;复位鼠标
int 33h
cmp ax,0ffffh             ;鼠标驱动程序检查
jz ok
mov dx,offset mess2
mov ah,9
int 21h
mov dx,offset mess1
mov ah,9
int 21h
_quit:
mov ah,4ch
int 21h
ok:
mov ax,1500h
mov bx,0
xor cx,cx
int 2fh                  ;取CD-ROM驱动器号
cmp cx,2
jg next1
mov dx,offset mess2
mov ah,9
int 21h
mov dx,offset err        ;CD-ROM出错
mov ah,9
int 21h
jmp _quit                ;退出

next1:
mov cd_rom_driver,cx
call init                ;初始化CD-ROM
cmp ax,0ffffh
jnz checkcd
mov dx,offset mess2
mov ah,9
int 21h
mov dx,offset err        ;CD-ROM出错
mov ah,9
int 21h
jmp _quit

checkcd:

mov ah,9
mov dx,offset mess2 ;显示信息
int 21h

mov ah,9
mov dx,offset usage
int 21h

call check               ;CD-AUDIO状态检查
mov byte ptr track,al
call pause               ;暂停
call play                ;播放

mov ax,000ch              ;鼠标事件设置
mov cx,00001010b
mov dx,ds
mov es,dx
mov dx,offset my          ;指向 my
int 33h

mov ax,3533h
int 21h                   ;取鼠标中断向量

mov cs:int33_off,bx
mov cs:int33_seg,es       ;保存原鼠标中断向量
mov ax,2533h
mov dx,offset new_33
push cs
pop ds
int 21h             ;设置新的鼠标中断,指向 new_33

mov dx,offset init_cd ;驻留内存
int 27h
mess1 db 'MOUSE NOT INSTALLED!',0dh,0ah,'$'
mess2 db 'MOUSE CD-PLAYER Ver 1.01 Copyright (c) ZDsoft.',0dh,0ah
      db 'Write by Zou Dan,1995,8',0dh,0ah
      db 'TELE (023)65311989-6023,POST CODE:630045',0dh,0ah
      db 'ADDRESS:No.80-7-2,East Village,Architectural University,ChongQing',0ah,0dh
      db 'OR No.51 Postbox,Math Department,East Part of ShiChuan University',0dh,0ah
      db 'Post CODE:610064,ShiChuan',0dh,0ah,'$'  
mess  db 'MOUSE CD-PLAYER ALREADY INSTALLED',0dh,0ah,'$'
usage db 'USAGE:',0dh,0ah     
      db '    STOP: Press LEFT,MIDDLE,RIGHT botton at the same time.',0dh,0ah
      db '          (For Three-Botton Mouse).',0dh,0ah
      db '     OR Move the mouse to TOP and press LEFT and RIGHT botton at the same time.',0dh,0ah
      db '          (This is special designed for Two-Botton Mouse.)',0dh,0ah             
      db 'PLAY Pre. TRACK: Move the mouse to the LEFT side and',0dh,0ah 
      db '                 press LEFT and RIGHT botton at the same time.',0dh,0ah  
      db 'PLAY Next TRACK: Move the mouse to the RIGHT side and',0dh,0ah
      db '                 press LEFT and RIGHT botton at the same time.',0dh,0ah,'$'          
err   db 'CD-ROM ERROR!',0dh,0ah,'$'

code ends
end start

⌨️ 快捷键说明

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