home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Interdit
/
pc-interdit.iso
/
sound
/
gusmod
/
gusasm.asm
< prev
next >
Wrap
Assembly Source File
|
1994-10-12
|
21KB
|
770 lines
.286
segment data
w equ word ptr
b equ byte ptr
num_voices equ 14
;**************************************************************************
;*** S E G M E N T D E D O N N E E S ***
;**************************************************************************
trouve db ?
;**************************************************************************
;*** D E C L A R T I O N D E S V A R I A B L E S ***
;**************************************************************************
Play_Voice equ 0
Stop_Voice equ 3
Bit8 equ 0
Bit16 equ 4
No_Loop equ 0
Mit_Loop equ 8
Unidirect equ 0
Bidirect equ 16
Go_forw equ 0
Go_Back equ 64
data ends
;**************************************************************************
;*** S E G M E N T D E C O D E ***
;**************************************************************************
segment code
assume cs:code, ds:data
;**************************************************************************
;*** D E C L A R A T I O N D E S R O U T I N E S ***
;**************************************************************************
u_base dw 240h
u_status dw u_base+006h
u_voice dw u_base+102h
u_command dw u_base+103h
u_Datalo dw u_base+104h
u_Datahi dw u_base+105h
u_DramIO dw u_base+107h
oldUVolumes dw 01000h,0B000h,0B100h,0B200h,0B300h,0B400h,0B500h,0B600h,0B700h
dw 0B800h,0B900h,0BA00h,0BB00h,0BC00h,0BD00h,0BE00h,0BF00h
dw 0C000h,0C100h,0C200h,0C300h,0C400h,0C500h,0C600h,0C700h
dw 0C800h,0C900h,0CA00h,0CB00h,0CC00h,0CD00h,0CE00h,0CF00h
dw 0D000h,0D100h,0D200h,0D300h,0D400h,0D500h,0D600h,0D700h
dw 0D800h,0D900h,0DA00h,0DB00h,0DC00h,0DD00h,0DE00h,0DF00h
dw 0E000h,0E100h,0E200h,0E300h,0E400h,0E500h,0E600h,0E700h
dw 0E800h,0E900h,0EA00h,0EB00h,0EC00h,0ED00h,0EE00h,0EF00h
UVolumes DW 1500h
DW 40004,42600,44752,45648,46544,47624,48448,49232
DW 50048,50584,51112,51656,52184,52584,52976,53376
DW 53752,54016,54280,54520,54768,55024,55280,55544
DW 55776,56048,56288,56536,56784,56992,57184,57384
DW 57616,57752,57888,58000,58112,58248,58368,58480
DW 58600,58720,58840,58960,59088,59208,59336,59464
DW 59584,59720,59816,59944,60072,60176,60312,60408
DW 60544,60648,60784,60888,60992,61064,61176,61248
Voice_Divisor db 43,40,37,35,33,31,30,28,27,26,25,24,23,22,21,20,20,19,18
FFtable dw 66, 70, 74, 78, 83, 88, 93, 99, 104, 111
dw 117, 124, 132, 139, 148, 156, 166, 176, 186, 197
dw 209, 221, 234, 248, 263, 279, 295, 313, 331, 351
dw 372, 394, 418, 442, 469, 497, 526, 557, 591, 626
dw 663, 702, 744, 788, 835, 885, 938, 993, 1052, 1115
dw 1181, 1251, 1326, 1405, 1488, 1577, 1671, 1770, 1875, 1987
dw 2105, 2230, 2362, 2503, 2652, 2809, 2977, 3154, 3341, 3540
Modoctave dw 1712,1616,1525,1440,1359,1283,1211
dw 1143,1078,961,907,856,808,763,720
dw 679,641,605,571,539,509,480,453,428
dw 404,381,360,340,321,303,286,270,254
dw 240,227,214,202,191,180,170,160,151
dw 143,135, 127,120,113,107,101,95,90
dw 85,80,76,71,67,64,60,57,54,50,47,45
dw 42,40,38,36,34,32,30
public U_StartVoice
public u_VoiceBalance
public u_VoiceVolume
public u_delay
public u_Initialize
public u_Voicefreq
public Ultra_Mem2Gus
public u_Voicedata
public ffacteur
public Note
public dos_getmem
public dos_freemem
public detect_gus
public init_gus_base
public GusSound_deb
public GusSound_fin
public voice_rampin
public voice_slide
u_delay proc pascal
; **************************************************************************
; *** Attendre le temps qu'il faut pour un Double-write ***
; **************************************************************************
mov dx,300h
in al,dx
in al,dx
in al,dx
in al,dx
in al,dx
in al,dx
in al,dx
ret
u_delay endp
U_StartVoice proc pascal Nr,Mode : byte
; **************************************************************************
; *** Lance la sortie sur un canal GUS ***
; **************************************************************************
mov dx,w u_voice ; Choisir la voix
mov al,byte ptr Nr
out dx,al
mov dx,w u_command
mov al,0 ; Mode de la voix
out dx,al
mov dx,w u_DataHi
mov al,Mode ; Poser l'octet MODE
out dx,al
ret
U_StartVoice endp
u_VoiceBalance proc pascal Nr,balance : byte
; **************************************************************************
; *** Règle la position Pan pour un canal (0 - 15) ***
; **************************************************************************
mov dx,w u_Voice ; Choisir la voix
mov al,byte ptr Nr
out dx,al
mov dx,w u_Command ; Commande Set Pan-Position
mov al,0Ch
out dx,al
mov dx,w u_dataHi ; Ecrire la position
mov al,balance
out dx,al
ret
u_VoiceBalance endp
u_VoiceVolume proc pascal Nr:byte,Vol:word
; **************************************************************************
; *** Règle le volume pour un canal (0 - 63) ***
; **************************************************************************
mov dx,w u_Voice ; Choisir la voix
mov al,Nr
out dx,al
mov dx,w u_Command ; Commande de définition du volume
mov al,9
out dx,al
mov dx,w u_DataLo ; Charge le volume GUS dans la table
mov di,vol ; et le définit
shl di,1
mov ax,word ptr [offset uVolumes + di]
out dx,ax
ret
u_VoiceVolume endp
u_Initialize proc near
; **************************************************************************
; *** Initialise la carte Ultrasound ***
; **************************************************************************
mov bx,w u_Command
mov cx,w u_datahi
mov dx,bx
mov al,4ch ; Choisir le registre d'initialisation
out dx,al
mov dx,cx
mov al,0 ; Exécuter l'initialisation
out dx,al
call u_delay ; Attendre
call u_delay
mov dx,bx
mov al,4ch
out dx,al
mov dx,cx
mov al,1 ; Terminer l'initialisation
out dx,al
call u_delay
call u_delay
mov dx,bx ; Reset du DMA Control Register
mov al,41h
out dx,al
mov dx,cx
mov al,0
out dx,al
mov dx,bx ; Reset du Timer Control Register
mov al,45h
out dx,al
mov dx,cx
mov al,0
out dx,al
mov dx,bx ; Reset du Sampling Control Register
mov al,49h
out dx,al
mov dx,cx
mov al,0
out dx,al
mov dx,bx ; Poser le nombre de voix
mov al,0Eh
out dx,al
add dx,2
mov al,Num_Voices
or al,0C0h
out dx,al
mov dx,w u_status ; Vider éventuellement les interrupts DMA
in al,dx
mov dx,bx
mov al,41h
out dx,al
mov dx,cx
in al,dx
mov dx,bx ; Vider éventuellement les interrupts de sampling
mov al,49h
out dx,al
mov dx,cx
in al,dx
mov dx,bx ; Lire le registre d'état de l'IRQ
mov al,8Fh ; ==> Il n'y a plus d'interruptions
out dx,al ; non traitées
mov dx,cx
in al,dx
push bx ; Désactive les voix dans la boucle
push cx
mov cx,0
@VoiceClearLoop:
mov dx,w u_Voice ; Choisir les voix
mov al,cl
out dx,al
inc dx
mov al,0 ; Poser le mode Voice
out dx,al
add dx,2
mov al,3 ; Arrêter les voix
out dx,al
sub dx,2 ; Poser le volume sur 0
mov al,0dh
out dx,al
add dx,2
mov al,3
out dx,al
inc cx
cmp cx,32 ; Répéter pour toutes les voix
jnz @VoiceClearLoop
pop cx
pop bx
mov dx,bx ; Traiter les interruptions
mov al,41h ; éventuelles
out dx,al
mov dx,cx
in al,dx
mov dx,bx
mov al,49h
out dx,al
mov dx,cx
in al,dx
mov dx,bx
mov al,8fh
out dx,al
mov dx,cx
in al,dx
mov dx,bx ; Exécuter un reset
mov al,4ch
out dx,al
mov dx,cx ; Activer l'IRQ master GF1
mov al,7
out dx,al
ret
u_Initialize endp
u_Voicefreq proc pascal Nr:byte,Freq:word
; **************************************************************************
; *** Règle la fréquence à laquelle le canal sera exécuté ***
; **************************************************************************
mov dx,w u_Voice ; Adresser la voix
mov al,Nr
out dx,al
mov dx,w u_Command ; Ecrire la commande pour la fréquence
mov al,1
out dx,al ; Freq := Fréquence DIV
xor bx,bx ; Voice_Divisor[num_voices-13]
mov bl,num_voices
mov ax,Freq
mov di,bx
sub di,14
xor bx,bx
xor dx,dx
mov bl,byte ptr [voice_Divisor+di]
div bx
mov dx,w u_DataLo
out dx,ax
ret
u_Voicefreq endp
Ultra_Mem2Gus proc pascal sampp:dword,start:dword,long:word
; **************************************************************************
; *** Copie un secteur de RAM dans la RAM de la carte ***
; **************************************************************************
push ds
push si
mov si,[bp+12] ; Segment
mov ds,si
mov si,[bp+10] ; Offset
mov dx,w u_Command ; Poser l'octet Hi de l'adresse de GUS-DRAM
mov al,44h
out dx,al
mov dx,w u_DataHi
mov ax,[bp+08] ; hstart
out dx,al
mov cx,[bp+4] ; Charger la longueur
@Copy_loop:
mov dx,w u_Command ; Poser l'octet Lo de l'adresse de GUS-DRAM
mov al,43h
out dx,al
mov dx,w u_DataLo
mov ax,[bp+06] ; lstart
out dx,ax
mov dx,w u_DramIo ; Charger et envoyer l'octet
lodsb
out dx,al
cmp word ptr [bp+06],0ffffh ; lstart = 0ffffh ?
je @depassement
inc word ptr [bp+06] ; lstart++
jmp @continuer
@depassement:
inc word ptr [bp+08] ; hstart ++
mov word ptr [bp+06],0 ; lstart sur 0
mov dx,w u_Command ; Poser l'adresse hi de l'adresse de la RAM GUS
mov al,44h
out dx,al
mov dx,w u_DataHi
mov ax,[bp+08] ; hstart
out dx,al
@continuer:
loop @copy_loop
pop si
pop ds
ret
Ultra_Mem2Gus endp
u_Voicedata proc pascal start,lsta,llong:dword,Nr:word
; **************************************************************************
; *** Définit les paramètre pour un canal ***
; **************************************************************************
mov dx,w u_Voice ; Choisir la voix
mov ax,Nr
out dx,al
mov dx,w u_command ; Définir le début de la voix
mov al,0ah
out dx,al
mov ax, word ptr [start+2]
mov cx, word ptr [start]
mov bx,cx
shr ax,7
shr cx,7
shl bx,9
or ax,bx
mov dx,w u_DataLo
out dx,ax
mov dx,w u_Command
mov al,0bh
out dx,al
mov dx,w u_datalo
mov ax,word ptr [start]
shl ax,9
out dx,ax
mov dx,w u_command ; Définir le début d'une boucle
mov al,2
out dx,al
mov ax, word ptr [lsta]
mov cx, word ptr [lsta+2]
mov bx,cx
shr ax,7
shr cx,7
shl bx,9
or ax,bx
mov dx,w u_DataLo
out dx,ax
mov dx,w u_Command
mov al,3
out dx,al
mov dx,w u_datalo
mov ax,word ptr [lsta]
shl ax,9
out dx,ax
mov dx,w u_command ; Définir la fin de la boucle
mov al,4
out dx,al
mov ax, word ptr [llong]
mov cx, word ptr [llong+2]
mov bx,cx
shr ax,7
shr cx,7
shl bx,9
or ax,bx
mov dx,w u_DataLo
out dx,ax
mov dx,w u_Command
mov al,5
out dx,al
mov dx,w u_datalo
mov ax,word ptr [llong]
shl ax,9
out dx,ax
ret
u_Voicedata endp
ffacteur proc pascal t:word
; **************************************************************************
; *** Renvoie la fréquence pour une tonalité en "t" ***
; **************************************************************************
mov di,t
sub di,5
shl di,1
mov ax,word ptr [offset fftable+di]
ret
ffacteur endp
Note proc pascal hauteur:word
; **************************************************************************
; *** Détermine le numéro pour une tonalité donnée d'un fichier MOD ***
; **************************************************************************
mov trouve,1
xor di,di
@boucle:
mov ax,word ptr Modoctave[di]
cmp hauteur,ax
ja note_trouve
add di,2
; cmp di,128
cmp di,140
jae @continuer_recherche
jmp @boucle
note_trouve:
mov trouve,0
@continuer_recherche:
mov ax,255
cmp trouve,0
jne fin_Note
mov ax,di
shr ax,1
inc ax
fin_Note:
ret
Note endp
dos_getmem proc pascal pointeur:dword,ensemble:word
; **************************************************************************
; *** Alloue un secteur (max. 64 Ko) dans la mémoire RAM de DOS ***
; **************************************************************************
push ds
mov bx,ensemble
shr bx,4
inc bx
mov ah,48h
int 21h
mov bx,w [pointeur+2]
mov ds,bx
mov bx,w [pointeur]
mov w [bx],0
mov w [bx+2],ax
pop ds
ret
dos_getmem endp
dos_freemem proc pascal pointeur:dword
; **************************************************************************
; *** Libère un secteur alloué par dos_getmem ***
; **************************************************************************
mov ax,word ptr [pointeur+2]
mov es,ax
mov ah,49h
int 21h
ret
dos_freemem endp
detect_gus proc near
; ***************************************************************************
; *** La routine sert à reconnaître la Gravis Ultrasound. Le port de base ***
; *** est reconnu. La procédure retourne 0 quand la carte a été trouvée, ***
; *** sinon la valeur 1. ***
; ***************************************************************************
mov di,1F0h
@detect_loop: ; Test des ports possibles dans une boucle
add di,10h
mov dx,di
add dx,103h ; Tente d'initialiser
mov al,4Ch
out dx,al
mov dx,di
add dx,105h
mov al,0
call u_delay
call u_delay
mov dx,di
add dx,103h
mov al,4Ch
out dx,al
mov dx,di
add dx,105h
mov al,0
mov dx,di ; Tentative d'écrire des données
add dx,103h ; dans la RAM de la carte
mov al,43h
out dx,al
mov dx,di
add dx,105h
mov al,0h
out dx,al
mov dx,di
add dx,103h
mov al,44h
out dx,al
mov dx,di
add dx,105h
mov al,0h
out dx,al
mov dx,di
add dx,107h
mov al,0AAh
out dx,al
call u_delay ; Attente, pour que la GF1
call u_delay ; ne puisse pas nous échapper
call u_delay
call u_delay
call u_delay
call u_delay
xor ax,ax ; Lecture en retour dans la RAM de la carte
mov dx,di
add dx,107h
in al,dx
cmp al,0AAh ; Valeur écrite = Valeur lue ?
je @Carte_trouvee ; Carte trouvée !
cmp di,280h
jae @Carte_non_trouvee ; Pas de carte à ce port :
jmp @detect_loop ; Tentative avec un nouveau port
@Carte_trouvee:
mov w u_base,di ; Initialiser le registre de base de la carte
mov ax,di
add ax,6
mov w u_status,ax
mov ax,di
add ax,102h
mov w u_voice,ax
mov ax,di
add ax,103h
mov w u_command,ax
mov ax,di
add ax,104h
mov w u_Datalo,ax
mov ax,di
add ax,105h
mov w u_Datahi,ax
mov ax,di
add ax,107h
mov w u_DramIO,ax
mov ax,0
jmp @Fin_Recherche
@Carte_non_trouvee:
mov ax,1
@Fin_Recherche:
ret
detect_gus endp
init_gus_base proc pascal gbase : word;
mov di,gbase
mov dx,di
add dx,103h ; Initialisiation de la recherche
mov al,4Ch
out dx,al
mov dx,di
add dx,105h
mov al,0
out dx,al ;?????
call u_delay
call u_delay
mov dx,di
add dx,103h
mov al,4Ch
out dx,al
mov dx,di
add dx,105h
mov al,1
out dx,al ;????
mov w u_base,di ; initialisation du registre de base de la carte
mov ax,di
add ax,6
mov w u_status,ax
mov ax,di
add ax,102h
mov w u_voice,ax
mov ax,di
add ax,103h
mov w u_command,ax
mov ax,di
add ax,104h
mov w u_Datalo,ax
mov ax,di
add ax,105h
mov w u_Datahi,ax
mov ax,di
add ax,107h
mov w u_DramIO,ax
mov ax,0
ret
init_gus_base endp
GusSound_fin proc near
; **************************************************************************
; *** Arrête l'emission de son de la GUS ***
; **************************************************************************
mov dx,w u_base
in al,dx
or al,2
out dx,al
ret
GusSound_fin endp
GusSound_deb proc near
; **************************************************************************
; *** Début de l'émission de son (Wavetable) de la GUS ***
; **************************************************************************
mov dx,w u_base
in al,dx
and al,0FDh
out dx,al
ret
GusSound_deb endp
voice_rampin proc pascal voix:byte,vol : word;
; **************************************************************************
; *** Un moyen de définir directement le volume d'une voix. ***
; *** Le player perd un peu de son agressivité, mais ***
; *** on réduit ainsi les craquements éventuels. ***
; **************************************************************************
mov dx,w u_voice ; Choisir la voix
mov al,byte ptr voix
out dx,al
mov dx,w u_command ; Définit le facteur de Ramping
mov al,6
out dx,al
mov dx,w u_datahi
mov al,00111111b
out dx,al
mov dx,w u_Command ; Modifie le volume actuel
mov al,9
out dx,al
mov dx,w u_datahi
mov al,00010010b
out dx,al
mov dx,w u_command ; Définit le volume de départ du ramping
mov al,7
out dx,al
mov dx,w u_datahi
mov al,00010010b
out dx,al
mov dx,w u_command ; Définit le volume final du Ramping
mov al,8
out dx,al
mov dx,w u_datahi
mov di,word ptr vol
shl di,1
mov ax,word ptr [offset uVolumes + di]
shr ax,8
out dx,al
mov dx,w u_command ; Direction du ramping dans le contrôle du volume
mov al,0dh ; Définit le registre
out dx,al
mov dx,w u_datahi
mov al,0
out dx,al
ret
voice_rampin endp
voice_slide proc pascal nr,speed : byte,vol : word;
mov dx,w u_voice ; choisir la voix
mov al,byte ptr nr
out dx,al
mov dx,w u_command ; définir le facteur de ramping
mov al,6
out dx,al
mov dx,w u_datahi
mov al,byte ptr speed
out dx,al
mov dx,w u_Command ; modifie le volume actuel
mov al,9
out dx,al
mov dx,w u_datahi
mov al,00010010b
out dx,al
mov dx,w u_command ; définit le volume du départ du ramping
mov al,7
out dx,al
mov dx,w u_datahi
mov al,00010010b
out dx,al
mov dx,w u_command ; définit le volume de fin du ramping
mov al,8
out dx,al
mov dx,w u_datahi
mov di,word ptr vol
shl di,1
mov ax,word ptr [offset uVolumes + di]
shr ax,8
out dx,al
mov dx,w u_command ; direction du ramping dans le contrôle du volume
mov al,0dh ; définit le registre
out dx,al
mov dx,w u_datahi
mov al,0
out dx,al
ret
voice_slide endp
public gus_speaker_on
gus_speaker_on proc pascal
mov dx,u_base
mov al,4
out dx,al
ret
gus_speaker_on endp
public position_voix
position_voix proc pascal voix : word
mov dx,w u_command
mov al,4
out dx,al
mov dx,w u_datahi
in ax,dx
mov cx,ax
ret
position_voix endp
public get_detected_base
get_detected_base proc pascal
mov ax,u_base
ret
get_detected_base endp
code ends
end