;*************************************************************************** ;* Driver pour le DAC avec des calculs 10bits ;* ;* Programmé par Sébastien Granjoux ;* Commencé le 03/01/95 ;* Modification le 03/01/95 IDEAL P386N INCLUDE "CRYSERR.INC" INCLUDE "CRYSDEV.INC" PUBLIC USEDAC BIOSSEG EQU 40h LPT1ADR EQU 08h SEGMENT CODE PARA PUBLIC USE16 'CODE' ASSUME cs:CODE,ds:CODE ;************************************************************************* ;* Fonction de detection du driver PROC USEDAC call USEDEVICE DEVICE <02h,'DACs=p$',OFFSET setdac,OFFSET startdac,OFFSET stopdac,OFFSET makedac,OFFSET defbpm,OFFSET peekdef,0,0,0> ENDP Counter DD 0 Count DD 0 OtherCount DW 0 ;************************************************************************** ;* Routine d'initialisation du DAC ;* ;* Entrée: ;* DS:SI adresse de la structure device (port de 1 à 4 inclus) ;* ;* Sortie: ;* AX code d'erreur si C=1 PROC setdac mov [(DEVICE PTR ds:si).irq],0 mov bx,[(DEVICE ptr ds:si).port] mov ax,BIOSSEG mov es,ax shl bx,1 mov ax,[es:bx+LPT1ADR-2] or ax,ax je @@no_lpt mov [cs:OFFSET port_dac+1],ax mov cl,[NbVoice] mov al,cl mov ah,-1 @@find_msbit: inc ah shr al,1 jne @@find_msbit mov [cs:OFFSET nbvoicediv1+2],ah mov [cs:OFFSET nbvoicediv2+2],ah call caloptvoltab clc ret @@no_lpt: mov ax,DAC_NOT_FOUND stc ret ENDP ;*************************************************************************** ;* Cette routine permet de commencer l'envoit du son sur un DAC ;* ;* Entrée: ;* DS:BX adresse de la structure DEVICE PROC startdac cli mov dx,cs mov ax,OFFSET sounddac xor bl,bl call setirq mov al,00110110b out 43h,al jmp $+2 jmp $+2 mov dx,1 mov ax,0D216h div [ds:MixRate] out 40h,al jmp $+2 jmp $+2 rol ax,8 out 40h,al jmp $+2 jmp $+2 rol ax,8 movzx ecx,ax mov eax,80000000h xor edx,edx div ecx add eax,eax mov [ds:Counter],eax shr eax,16 mov [ds:OtherCount],ax mov ax,[ds:VoicesLen] sub [ds:OtherCount],ax mov [ds:Count],1 ; call setautoeoi sti ret ENDP ;************************************************************************** ;* cette procédure est en fait un bloc que l'on doit mettre à ;* l'adresse Voices PROC makedac FAR mov cl,[NbVoice] sub cl,2 push cx mov di,OFFSET Voice1 mov dx,[(VOICE PTR di).effet] call dx mov di,[ds:OFFSET SoundPage] mov bx,[(VOICE PTR Voice1).play] shl bx,1 xor edx,edx mov dx,[word ptr ds:bx+OFFSET Notes] ror edx,10 mov cx,[(VOICE PTR Voice1).samplen] les esi,[(VOICE PTR Voice1).adrvoc] mov bx,[(VOICE PTR Voice1).replen] cmp si,cx jbe @@ok1 @@adjust1: sub si,bx cmp si,cx ja @@adjust1 @@ok1: mov bx,OFFSET VolumeTab mov al,[MasterVol] and al,[(VOICE PTR Voice1).mute] mul [(VOICE PTR Voice1).volume] add bh,ah push ebp @@voix1: add esi,edx mov al,[byte ptr es:si] adc esi,edx xlat mov ah,al mov al,[byte ptr es:si] adc si,0 xlat mov [ds:di+OFFSET SoundBuf],ax mov [word ptr ds:di+OFFSET SoundBuf+BUF_LEN],0 add di,2 cmp di,bp jne @@voix1 rol ebp,16 xor di,di cmp bp,BUF_LEN jne @@voix1 pop ebp mov [dword ptr ((VOICE PTR Voice1).adrvoc)],esi pop cx mov di,OFFSET Voice1+SIZE VOICE @@next_voice: push cx mov dx,[(VOICE ptr ds:di).effet] call dx mov bx,[(VOICE ptr ds:di).play] shl bx,1 xor edx,edx mov dx,[word ptr ds:bx+OFFSET Notes] ror edx,10 mov cx,[(VOICE ptr ds:di).samplen] les esi,[(VOICE ptr ds:di).adrvoc] mov bx,[(VOICE ptr ds:di).replen] cmp si,cx jbe @@ok2 @@adjust2: sub si,bx cmp si,cx ja @@adjust2 @@ok2: mov bx,OFFSET VolumeTab mov al,[MasterVol] and al,[(VOICE PTR ds:di).mute] mul [(VOICE PTR ds:di).volume] add bh,ah push di push ebp mov di,[ds:OFFSET SoundPage] @@voix2: add esi,edx mov al,[byte ptr es:si] adc esi,edx xlat mov ah,al mov al,[byte ptr es:si] adc si,0 xlat add [ds:di+OFFSET SoundBuf],al adc [byte ptr ds:di+OFFSET SoundBuf+BUF_LEN],0 add [ds:di+OFFSET SoundBuf+1],ah adc [byte ptr ds:di+OFFSET SoundBuf+BUF_LEN+1],0 add di,2 cmp di,bp jne @@voix2 rol ebp,16 xor di,di cmp bp,BUF_LEN jne @@voix2 pop ebp pop di mov [dword ptr ((VOICE ptr ds:di).adrvoc)],esi add di,SIZE VOICE pop cx dec cl jne @@next_voice mov dx,[(VOICE ptr ds:di).effet] call dx mov bx,[(VOICE ptr ds:di).play] shl bx,1 xor edx,edx mov dx,[word ptr ds:bx+OFFSET Notes] ror edx,10 mov cx,[(VOICE ptr ds:di).samplen] les esi,[(VOICE ptr ds:di).adrvoc] mov bx,[(VOICE ptr ds:di).replen] cmp si,cx jbe @@ok4 @@adjust4: sub si,bx cmp si,cx ja @@adjust4 @@ok4: mov bx,OFFSET VolumeTab mov al,[MasterVol] and al,[(VOICE ptr ds:di).mute] mul [(VOICE ptr ds:di).volume] add bh,ah push di mov di,[ds:OFFSET SoundPage] xor ah,ah @@voix4: add esi,edx mov al,[byte ptr es:si] adc si,0 xlat add al,[ds:di+OFFSET SoundBuf] adc ah,[ds:di+OFFSET SoundBuf+BUF_LEN] nbvoicediv1: shr ax,2 mov [byte ptr ds:di+OFFSET SoundBuf],al add esi,edx mov al,[byte ptr es:si] adc si,0 xlat add al,[ds:di+OFFSET SoundBuf+1] adc ah,[ds:di+OFFSET SoundBuf+BUF_LEN+1] nbvoicediv2: shr ax,2 mov [byte ptr ds:di+OFFSET SoundBuf+1],al add di,2 cmp di,bp jne @@voix4 rol ebp,16 xor di,di cmp bp,BUF_LEN jne @@voix4 pop di mov [dword ptr ((VOICE ptr ds:di).adrvoc)],esi @@fin4voice: shr ebp,16 and bp,65535-BUF_LEN mov [word ptr ds:OFFSET SoundPage],bp mov [byte ptr cs:OFFSET switch_makemod],1Eh pop edi pop esi pop ebp pop es pop ds ret ENDP ;*************************************************************************** ;* interruption 8 permettant d'envoyer le son sur un port parallèle PROC sounddac FAR push ax push bx mov bx,[cs:OFFSET SoundPtr] inc bx and bx,65535-BUF_LEN mov [cs:OFFSET SoundPtr],bx mov al,[cs:bx+OFFSET SoundBuf] mov bx,dx port_dac: mov dx,378h out dx,al mov dx,bx pop bx dec [word cs:OFFSET Count+2] irq_switch: jle @@imakemod mov al,60h out 20h,al pop ax iret @@int08: mov ax,[word ptr cs:OFFSET Counter+2] xchg ax,[cs:OtherCount] add [cs:OFFSET Count+2],ax sub [cs:OtherCount],ax add [byte ptr cs:OFFSET irq_switch+1],OFFSET @@imakemod - OFFSET @@int08 pop ax jmp [dword ptr cs:OldIrq] @@imakemod: mov al,60h out 20h,al mov ax,[cs:VoicesLen] cmp ax,[cs:OtherCount] jb @@next_make xchg ax,[cs:OtherCount] sub [cs:OtherCount],ax mov [cs:OFFSET Count+2],ax mov ax,[word ptr cs:Counter] add [cs:OFFSET Count],ax sub [byte ptr cs:OFFSET irq_switch+1],OFFSET @@imakemod - OFFSET @@int08 pop ax jmp IMAKEMOD @@next_make: sub [cs:OtherCount],ax add [word ptr cs:OFFSET Count+2],ax pop ax jmp IMAKEMOD ENDP ;*************************************************************************** ;* Cette routine permet d'arreter l'envoit du son sur un DAC PROC stopdac cli mov al,00110110b out 43h,al xor al,al out 40h,al out 40h,al ; call reseteoi ret ENDP ENDS END