home *** CD-ROM | disk | FTP | other *** search
- ;***************************************************************************
- ;* Driver pour la GUS
- ;*
- ;* Programmé par Sébastien Granjoux
- ;* Commencé le 07/01/95
- ;* Modification le 07/01/95
-
- IDEAL
- P386N
-
- INCLUDE "CRYSLOAD.INC"
- INCLUDE "CRYSERR.INC"
- INCLUDE "CRYSDEV.INC"
-
- PUBLIC USEGUS
-
- SEGMENT CODE PARA PUBLIC USE16 'CODE'
-
- ASSUME cs:CODE,ds:CODE
-
- ;*************************************************************************
- ;* Fonction de detection du driver
-
- PROC USEGUS
-
- call USEDEVICE
- DEVICE <4,'ULTRASNDs=p,d,i$',OFFSET setgus,OFFSET startgus,OFFSET stopgus,OFFSET makegus,OFFSET defbpmgus,OFFSET peekgus,0,0,0>
-
- ENDP
-
- RAMPDELAY EQU 4A9h
-
- Compteur DD 0
- Compte DD 0
- BPMspeed DW 0
-
- STRUC GUSDATA
-
- action DB ?
- DW ?
- DB ?
- note DW ?
- volume DW ?
- repadr DD ?
- endadr DD ?
- curadr DD ?
- DD ?
- DD ?
- DD ?
-
- ENDS
-
- GusMem DD 0
- GusSample DD MAX_INST DUP (?) ; Adresse des samples dans la mémoire de la GUS
-
- ;***************************************************************************
- ;* Routine permettant d'écrire un octet dans la GUS
- ;*
- ;* Entrée:
- ;* DX adresse de port de la GUS
- ;* EBX adresse où écrire
- ;* AL donné à écrire
-
- PROC putgus
-
- push cx
-
- mov cl,al
- mov al,43h
- out dx,al
-
- inc dx
- mov eax,ebx
- out dx,ax
-
- dec dx
- mov al,44h
- out dx,al
-
- add dx,2
- shr eax,16
- out dx,al
-
- add dx,2
- mov al,cl
- out dx,al
-
- sub dx,4
-
- pop cx
-
- ret
-
- ENDP
-
- ;***************************************************************************
- ;* Routine permettant de lire un octet de la RAM de la GUS
- ;*
- ;* Entrée:
- ;* DX adresse de port de la GUS
- ;* EBX adresse à lire
- ;*
- ;* Sortie:
- ;* AL octet lus
-
- PROC getgus
-
- mov al,43h
- out dx,al
-
- inc dx
- mov eax,ebx
- out dx,ax
-
- dec dx
- mov al,44h
- out dx,al
-
- add dx,2
- shr eax,16
- out dx,al
-
- add dx,2
- in al,dx
-
- sub dx,4
-
- ret
-
- ENDP
-
- ;***************************************************************************
- ;* Envoit une commande à la GUS
- ;*
- ;* Entrée:
- ;* DX adresse de port de la GUS
- ;* AL commande à envoyer
- ;* AH argument de la commande
-
- PROC putcom
-
-
- out dx,al
-
- add dx,2
- mov al,ah
- out dx,al
-
- sub dx,2
-
- ret
-
- ENDP
-
- ;***************************************************************************
- ;* Routine d'initialisation de la GUS
-
- PROC setgus
-
- add [(DEVICE ptr ds:si).port],103h
- mov dx,[(DEVICE ptr ds:si).port]
-
- mov ax,4ch ;Reset de la GUS
- call putcom
-
- add dx,4
- REPT 14
- in al,dx
- ENDM
- sub dx,4
-
- mov ax,14ch
- call putcom
-
- add dx,4
- REPT 14
- in al,dx
- ENDM
- sub dx,4
-
- xor ebx,ebx ; Test la mémoire de la GUS
- @@test_mem:
-
- mov al,0AAh ; Ecrit 55AAh en 00000h
- call putgus
- inc ebx
- mov al,055h
- call putgus
-
- call getgus ; Lit 16 bits en 00000h
- mov ch,al
- dec ebx
- call getgus
- mov cl,al
-
- add ebx,256*1024
- cmp ebx,(1024+256)*1024
- je @@enough_mem
- cmp cx,55aah
- je @@test_mem
-
- @@enough_mem:
- sub ebx,256*1024
- mov [GusMem],ebx
- jnz @@find_gus
-
- mov ax,GUS_NOT_FOUND ;Pas de gus
- stc
- ret
-
- @@find_gus:
-
- mov [ds:MixRate],4400
- mov [(DEVICE PTR ds:si).irq],0
- mov [(DEVICE ptr ds:si).port],dx
- mov [ds:OFFSET port_gus1+1],dx
- mov [ds:OFFSET port_gus2+1],dx
-
- mov ax,0041h ; couche le DMA
- call putcom
-
- mov ax,0045h ; couche les timers
- call putcom
-
- mov ax,0049h ; pas de sampling
- call putcom
-
- mov ax,0cd0eh
- call putcom
-
- mov [ds:MixRate],4410
- mov al,SIZE GUSDATA ;32*nombre de voix
- mov cl,[byte ptr ds:OFFSET NbVoice]
- mul cl
- mov [ds:VoicesLen],ax
-
- push si
-
- mov si,OFFSET Instrument1
- mov di,OFFSET GusSample+4
- xor ebx,ebx
- mov cl,MAX_INST
- @@next_inst:
- push cx
-
- mov [ds:di],ebx
- push di
- push si
-
- mov ax,[(INSTRUMENT ptr ds:si).adrseg]
- mov es,ax
- xor di,di
- mov cx,[(INSTRUMENT ptr ds:si).length]
-
- or cx,cx
- je @@no_inst
-
- add cx,SAMPLE_BORDER
-
- xor si,si
- @@next_byte:
- lods [byte ptr es:si]
- call putgus
- inc ebx
- dec cx
- jne @@next_byte
-
- @@no_inst:
- pop si
- pop di
- pop cx
-
- add si,SIZE INSTRUMENT
- add di,4
-
- dec cl
- jne @@next_inst
-
- cmp ebx,[GusMem]
- ja @@not_enough_mem
-
- mov ax,ds
- mov es,ax
- mov di,OFFSET VolumeTab ; remplit la table de volume
- mov dx,7 ; valeur intial
- @@fill_tab:
-
- mov ax,dx
- or ah,ah
- mov ah,15
- jnz @@find_dec
- @@next_dec:
- dec ah
- shl al,1
- jnc @@next_dec
- @@find_dec:
- shl ax,4
- stosw
- add dx,4 ; coefficiant
- cmp di,OFFSET VolumeTab+65*2
- jbe @@fill_tab
- pop si
-
-
- clc
-
- ret
-
- @@not_enough_mem:
-
- mov ax,NOT_ENOUGH_GUS
- pop bx
- stc
- ret
- ENDP
-
-
-
- ;***************************************************************************
- ;* Commence à envoyer les données sur la GUS
-
- PROC startgus
-
- mov dx,[(DEVICE ptr ds:si).port]
-
- mov ch,31
- @@next_voices:
- dec dx
- mov al,ch
- out dx,al
- inc dx
-
- mov ax,0800h ; 800h loop enable
- call putcom ; voice mode
-
- mov cl,ch
- inc cl
- and cl,1
- mov ax,030ch
- jz @@right
- mov ah,0Ch
- @@right:
- call putcom ; pan register 3 et 12
-
- mov ax,20dh ; stop les volumes ramps
- call putcom
-
- mov ax,3f06h ;changement de volume rapide
- call putcom
-
- mov al,9
- out dx,al ; volume à 0
- inc dx
- xor ax,ax
- out dx,ax
- dec dx
-
- dec ch
- jge @@next_voices
-
- mov ax,34ch ;Allume le haut parleur
- call putcom
-
- sub dx,103h
- mov al,1h
- out dx,al
- add dx,103h
-
- mov [word ptr cs:OFFSET gus_switch+1],OFFSET soundgus1-OFFSET gus_switch+3
-
- cli
- mov ax,OFFSET soundgus
- mov dx,cs
- xor bl,bl
- call setirq
-
- mov al,00110110b ;00110110b
- out 43h,al
-
- mov ax,[BPMspeed] ; interruption a 50Hz
- out 40h,al
- rol ax,8
- out 40h,al
- rol ax,8
-
- movzx ecx,ax
- mov eax,80000000h
- xor edx,edx
- div ecx
- add eax,eax
- mov [ds:Compteur],eax
- mov [ds:Compte],eax
-
- call setautoeoi
- sti
-
- ret
-
- ENDP
-
- ;***************************************************************************
- ;* Procédure qui place les données du son dans le buffer
-
- PROC makegus FAR
-
- mov cl,[NbVoice]
- mov di,OFFSET Voice1
- mov si,[ds:OFFSET SoundPage]
- @@next_voice:
- push cx
-
- mov dx,[(VOICE ptr ds:di).effet]
- call dx
-
- mov bx,[(VOICE ptr ds:di).play]
- add bx,bx
- mov dx,[word ptr ds:bx+OFFSET Notes]
- mov [(GUSDATA ptr ds:si+OFFSET SoundBuf).note],dx
-
- mov al,[MasterVol]
- and al,[(VOICE ptr ds:di).mute]
- mul [(VOICE ptr ds:di).volume]
- mov bl,ah
- xor bh,bh
- shl bx,1
- mov ax,[OFFSET VolumeTab+bx]
- mov [(GUSDATA ptr ds:si+OFFSET SoundBuf).volume],ax
-
- mov bl,[(VOICE ptr ds:di).inst]
- and bx,1fh
- mov [(VOICE ptr ds:di).inst],bl
- shl bx,2
- mov ch,[(VOICE ptr ds:di).gusinf]
- mov [(VOICE ptr ds:di).gusinf],0
- mov [(GUSDATA ptr ds:si+OFFSET SoundBuf).action],ch
-
- test ch,01h
- jz @@no_loadadr1
-
- xor eax,eax
- mov ax,[(VOICE ptr ds:di).samplen]
- add eax,[ds:bx+OFFSET GusSample]
- mov [(GUSDATA ptr ds:si+OFFSET SoundBuf).endadr],eax
-
- xor eax,eax
- mov ax,[(VOICE ptr ds:di).samplen]
- sub ax,[(VOICE ptr ds:di).replen]
- add eax,[ds:bx+OFFSET GusSample]
- mov [(GUSDATA ptr ds:si+OFFSET SoundBuf).repadr],eax
-
- @@no_loadadr1:
-
- test ch,02h
- jz @@no_loadcur1
-
- mov eax,[(dword ptr (VOICE ptr ds:di).adrvoc)]
- and eax,0ffffh
- add eax,[ds:bx+OFFSET GusSample]
- mov [(GUSDATA ptr ds:si+OFFSET SoundBuf).curadr],eax
-
- @@no_loadcur1:
-
- add si,SIZE GUSDATA
- add di,SIZE VOICE
- pop cx
- dec cl
- jne @@next_voice
-
- and si,65535-BUF_LEN
- mov [word ptr ds:OFFSET SoundPage],si
- 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 la gus
-
- PROC soundgus FAR
-
- push eax
- push bx
- push cx
- push dx
-
- gus_switch:
- jmp soundgus2
-
- soundgus1:
- mov ax,RAMPDELAY ; interruption à 1kHz
- out 40h,al
- mov al,ah
- out 40h,al
-
- mov [word ptr cs:OFFSET gus_switch+1],OFFSET soundgus2-OFFSET gus_switch+3
-
- mov bx,[cs:OFFSET SoundPtr]
-
- port_gus1:
- mov dx,323h
-
- mov cl,[byte ptr cs:OFFSET NbVoice]
- dec cl
- @@next_voice:
- dec dx
- mov al,cl
- out dx,al
-
- inc dx
-
- test [(GUSDATA ptr cs:bx+OFFSET SoundBuf).action],4
- jz @@no_voice_off
-
- mov al,09h
- out dx,al
-
- inc dx
- mov al,[cs:OFFSET VolumeTab]
- out dx,al
- dec dx
-
- mov al,89h
- out dx,al
-
- add dx,2
- in al,dx
- mov ah,al
- sub dx,2
-
- mov al,7
- out dx,al
-
- xor al,al
- mov ch,[cs:OFFSET VolumeTab+1]
-
- cmp ch,ah
- ja @@inc_vol
- mov al,40h
- xchg ch,ah
- @@inc_vol:
-
- add dx,2
- xchg al,ah
- out dx,al
- sub dx,2
-
- mov al,8
- out dx,al
-
- add dx,2
- mov al,ch
- out dx,al
- sub dx,2
-
- mov al,0dh
- out dx,al
-
- add dx,2
- mov al,ah
- out dx,al
- sub dx,2
-
- @@no_voice_off:
-
- add bx,SIZE GUSDATA
-
- dec cl
- jns @@next_voice
-
- pop dx
- pop cx
- pop bx
-
- dec [word cs:OFFSET Compte+2]
- jz @@int08
-
- pop eax
- iret
-
- @@int08:
- mov eax,[cs:Compteur]
- add [cs:OFFSET Compte],eax
- pop eax
- jmp [dword ptr cs:OldIrq]
-
-
- soundgus2:
- mov ax,[cs:BPMspeed] ; interruption à 50Hz
- out 40h,al
- mov al,ah
- out 40h,al
-
- mov [word ptr cs:OFFSET gus_switch+1],OFFSET soundgus1-OFFSET gus_switch+3
-
- mov bx,[cs:OFFSET SoundPtr]
-
- port_gus2:
- mov dx,323h
-
- mov cl,[byte ptr cs:OFFSET NbVoice]
- dec cl
- @@next_voice2:
- dec dx
- mov al,cl
- out dx,al
-
- inc dx
-
- mov ch,[(GUSDATA ptr cs:bx+OFFSET SoundBuf).action]
-
- test ch,1
- jz @@no_new_inst
-
- mov al,05h
- out dx,al
-
- inc dx
- mov eax,[(GUSDATA ptr cs:bx+OFFSET SoundBuf).endadr]
- rol eax,9
- out dx,ax
- dec dx
-
- mov al,04h
- out dx,al
-
- inc dx
- ror eax,16
- out dx,ax
- dec dx
-
- mov al,03h
- out dx,al
-
- inc dx
- mov eax,[(GUSDATA ptr cs:bx+OFFSET SoundBuf).repadr]
- rol eax,9
- out dx,ax
- dec dx
-
- mov al,02h
- out dx,al
-
- inc dx
- ror eax,16
- out dx,ax
- dec dx
-
- @@no_new_inst:
-
- test ch,2
- jz @@no_loadcur
-
- mov al,0
- out dx,al
-
- add dx,2
- mov al,3
- out dx,al
- sub dx,2
-
- REPT 6
- in al,dx
- ENDM
-
- add dx,2
- mov al,3
- out dx,al
- sub dx,2
-
- mov al,0bh
- out dx,al
-
- inc dx
- mov eax,[(GUSDATA ptr cs:bx+OFFSET SoundBuf).curadr]
- shl eax,9
- out dx,ax
- dec dx
-
- mov al,0ah
- out dx,al
-
- inc dx
- ror eax,16
- out dx,ax
- dec dx
-
- mov al,0
- out dx,al
-
- add dx,2
- mov al,8
- out dx,al
- sub dx,2
-
- REPT 6
- in al,dx
- ENDM
-
- add dx,2
- mov al,8
- out dx,al
- sub dx,2
-
-
- @@no_loadcur:
-
- test ch,8
- jnz @@ramp_vol
-
- jmp @@ok_vol
-
- @@ramp_vol:
-
- mov al,89h
- out dx,al
-
- add dx,2
- in al,dx
- mov ah,al
- sub dx,2
-
- mov al,7
- out dx,al
-
- xor al,al
- mov ch,[byte ptr ((GUSDATA ptr cs:bx+OFFSET SoundBuf).volume)+1]
-
- cmp ch,ah
- ja @@inc_vol2
- mov al,40h
- xchg ch,ah
- @@inc_vol2:
-
- add dx,2
- xchg al,ah
- out dx,al
- sub dx,2
-
- mov al,8
- out dx,al
-
- add dx,2
- mov al,ch
- out dx,al
- sub dx,2
-
- mov al,09h
- out dx,al
-
- inc dx
- mov al,[byte ptr ((GUSDATA ptr cs:bx+OFFSET SoundBuf).volume)]
- out dx,al
- dec dx
-
- mov al,0dh
- out dx,al
-
- add dx,2
- mov al,ah
- out dx,al
- sub dx,2
-
- @@ok_vol:
- mov al,1
- out dx,al
-
- inc dx
- mov ax,[(GUSDATA ptr cs:bx+OFFSET SoundBuf).note]
- out dx,ax
- dec dx
-
- add bx,SIZE GUSDATA
-
- dec cl
- jns @@next_voice2
-
- and bx,65535-BUF_LEN
- mov [cs:OFFSET SoundPtr],bx
-
- pop dx
- pop cx
- pop bx
- pop eax
-
- jmp IMAKEMOD
-
-
- ENDP
-
-
- ;***************************************************************************
- ;* cette routine permet d'arreter l'envoit du son sur la gus
-
- PROC stopgus
-
- mov dx,[(DEVICE ptr ds:si).port]
-
- mov ax,14ch ;Eteint le haut parleur
- call putcom
-
- sub dx,103h
- mov al,3
- out dx,al
- add dx,103h
-
- mov cl,31
- @@next_voices:
- dec dx
- mov al,cl
- out dx,al
- inc dx
-
- mov ax,0300h ; 800h loop enable
- call putcom ; voice mode
-
-
- mov ax,030dh ; stop les volumes ramps
- call putcom
-
- dec cl
- jns @@next_voices
-
- cli
- mov al,00110110b
- out 43h,al
- xor al,al
- out 40h,al
- out 40h,al
-
- call reseteoi
-
- ret
-
- ENDP
-
- ;***************************************************************************
- ;* Change la vitesse en BPM
- ;*
- ;* Entrée:
- ;* AL nouvelle vitesse
-
- PROC defbpmgus
-
- movzx cx,al
- mov ax,8426h ;1193180*2.5
- mov dx,2dh
- div cx
- mov [BPMspeed],ax
- sub [BPMspeed],RAMPDELAY
-
- movzx ecx,ax
- mov eax,80000000h
- xor edx,edx
- div ecx
- add eax,eax
- mov [ds:Compteur],eax
- mov [ds:Compte],eax
-
- ret
-
- ENDP
-
- ;***************************************************************************
- ;* Récupère un l'octet joué par la GUS
- ;*
- ;* Entrée:
- ;* AL numero de la voix
-
- PROC peekgus
-
- mov dx,[(DEVICE ptr ds:bx).port]
- dec dx
- inc al
- cli
- out dx,al
- inc dx
-
- dec al
- mov ah,SIZE VOICE
- mul ah
- mov bx,ax
- add bx,OFFSET Voice1
- push bx
-
- mov al,8Ah
- out dx,al
-
- inc dx
- in ax,dx
- mov bx,ax
- shl ebx,16
- dec dx
-
- mov al,8Bh
- out dx,al
-
- inc dx
- in ax,dx
- mov bx,ax
- dec dx
-
- shr ebx,9
-
- mov al,43h
- out dx,al
-
- inc dx
- mov ax,bx
- out dx,ax
- dec dx
-
- mov al,44h
- out dx,al
- add dx,2
-
- shr ebx,16
- mov ax,bx
- out dx,al
-
- add dx,2
- in al,dx
- sub dx,4
- sti
-
- pop bx
- mov dl,[(VOICE PTR ds:bx).volume]
- mul dl
-
- shr ax,6
-
- ret
-
- ENDP
-
- ENDS
-
- END