只要你想听CD,它在任何时候(DOS下,游戏下都可以)用鼠标激活,鼠标控制,为你播放.并提供了选曲和暂停功能,这为光驱上无直接播放建的朋友提供了莫大的方便.该程序思路巧妙,利用INT 33H的现有鼠标功能,巧妙扩展,达到任何条件下激活的能力!!如果你有兴趣,可以把他改为鼠标控制XXXXXX的程序,随时激活,方便无比!!!
源码如下:
;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  
|