;***************************************************************************
;*	Fonctions diverses utilis‚es par les diff‚rents drivers
;*
;* Programm‚ par S‚bastien Granjoux
;* Commenc‚ le 12/01/95
;* Modification le 12/01/95

IDEAL
P386N

INCLUDE "CRYSERR.INC"
INCLUDE "CRYSDEV.INC"

SEGMENT CODE PARA PUBLIC USE16 'CODE'

ASSUME cs:CODE,ds:CODE

;*************************************************************************
;*	Calcul la table multiplication pour le volume
;*
;* Entr‚e:
;*	CL	nombre de voix utilis‚

PROC	calvoltab

	mov	di,OFFSET VolumeTab	;remplit la table de multiplication
	xor	dl,dl
@@fill_tab:
	xor	dh,dh
@@fill_line:
	mov	al,dh
	imul	dl
	sar	ax,6
	xor	ah,ah
	add	al,128
	div	cl
	mov	[ds:di],al
	inc	di
	inc	dh
	jne	@@fill_line
	inc     dl
	cmp	dl,64
	jbe	@@fill_tab

	ret
ENDP

;*************************************************************************
;*	Calcul la table multiplication 8 bits optimal pour le volume
;*
;* Entr‚e:
;*	CL	nombre de voix utilis‚

PROC	caloptvoltab

	mov	ch,cl
	mov	cl,-1
	mov	al,ch
@@find_msbit:
	inc	cl
	shr	al,1
	jne	@@find_msbit
	mov	ax,100h
	shl	ah,cl
	xor	dx,dx
	shr	cx,8
	div	cx
	mov	cx,ax

	mov	di,OFFSET VolumeTab	;remplit la table de multiplication
	xor	bl,bl
@@fill_tab:
	xor	bh,bh
@@fill_line:
	mov	al,bl
	imul	bh
;	add	ax,31		; Arrondie pour WP
	sar	ax,6
;	cmp	ah,1
;	jne	@@no_overflow	; Et sans d‚bordement en plus !
;	mov	al,255
;@@no_overflow:
	xor	ah,ah
	add	al,128
	mul	cx
	mov	[ds:di],ah
	inc	di
	inc	bh
	jne	@@fill_line
	inc     bl
	cmp	bl,64
	jbe	@@fill_tab

	ret
ENDP


;***************************************************************************
;*	Passe en mode fin d'interruption automatique
;*

PROC	setautoeoi

	mov	al,11h
	out	20h,al
	jmp	$+2
	jmp	$+2
	mov	al,8h
	out	21h,al
	jmp	$+2
	jmp	$+2
	mov	al,4h
	out	21h,al
	jmp	$+2
	jmp	$+2
	mov	al,3h
	out	21h,al
	jmp	$+2
	jmp	$+2

	ret

ENDP

;***************************************************************************
;*	Revient dans le mode fin d'interruption normale

PROC	reseteoi

	mov	al,11h
	out	20h,al
	jmp	$+2
	jmp	$+2
	mov	al,8h
	out	21h,al
	jmp	$+2
	jmp	$+2
	mov	al,4h
	out	21h,al
	jmp	$+2
	jmp	$+2
	mov	al,1h
	out	21h,al
	jmp	$+2
	jmp	$+2

	ret

ENDP

;***************************************************************************
;*	Change la vitesse en BPM
;*
;* Entr‚e:
;*	AL	nouvelle vitesse

PROC	defbpm

	movzx	cx,al
	mov	ax,[MixRate]
	mov	dx,25
	mul	dx
	div	cx
	inc	ax
	and	ax,0fffch
	mov	[VoicesLen],ax
	ret

ENDP
;***************************************************************************
;*	RecupŠre un l'octet courant du buffer
;*
;* Entr‚e:
;*	AL	numero de la voix

PROC	peekdef

	mov	ah,SIZE VOICE
	mul	ah
	mov	si,ax
	add	si,OFFSET Voice1

	mov	dl,[(VOICE PTR ds:si).volume]
	lds	edi,[(VOICE PTR ds:si).adrvoc]
	mov	al,[ds:di]
	mul	dl

	shr	ax,6
	ret

ENDP

;****************************************************************************
;*	RecupŠre l'adresse d'une interruption
;*
;* Entr‚e:
;*	BL	numero d'interruption
;*
;* Sortie:
;*	AX	offset de la routine d'interruption
;*	DX	segment de la routine d'interruption

PROC	getirq

	cmp	bl,8
	jb	@@first_pic
	add	bl,60h
@@first_pic:
	add	bl,8
	xor	bh,bh
	shl	bx,2
	push	ds
	xor	ax,ax
	mov	ds,ax
	mov     ax,[ds:bx]
	mov	dx,[ds:bx+2]
	pop	ds
	ret

ENDP

;*****************************************************************************
;*      Fixe un vecteur d'interruption (ATTENTION il faut avoir enlev‚ les
;*	interruption auparavant dans le programme principal)
;*
;* Entr‚e:
;*	BL	numero de l'irq
;*	DX:AX	adresse la routine sous interruption

PROC	setirq

	cmp	bl,8
	jb	@@first_pic
	add	bl,60h
@@first_pic:
	add	bl,8
	xor	bh,bh
	shl	bx,2
	push	ds
	push	ax
	xor	ax,ax
	mov	ds,ax
	pop	ax
	mov	[ds:bx],ax
	mov	[ds:bx+2],dx
	pop	ds
	ret

ENDP

;*************************************************************************
;*	Table d'amplification pour l'adlib et le speaker

AMPLI8	        DB 40h,40h,40h,40h,40h,40h,40h,40h
		DB 40h,40h,3fh,3fh,3fh,3fh,3fh,3fh
		DB 3fh,3fh,3fh,3fh,3fh,3fh,3eh,3eh
		DB 3eh,3eh,3eh,3eh,3eh,3eh,3eh,3eh
		DB 3dh,3dh,3dh,3dh,3dh,3dh,3dh,3dh
		DB 3dh,3ch,3ch,3ch,3ch,3ch,3ch,3ch
		DB 3ch,3ch,3ch,3bh,3bh,3bh,3bh,3bh
		DB 3bh,3bh,3bh,3bh,3bh,3ah,3ah,3ah
		DB 3ah,3ah,3ah,3ah,3ah,3ah,3ah,39h
		DB 39h,39h,39h,39h,39h,39h,39h,39h
		DB 39h,38h,38h,38h,38h,38h,38h,38h
		DB 38h,37h,37h,37h,37h,37h,36h,36h
		DB 36h,36h,35h,35h,35h,35h,34h,34h
		DB 34h,33h,33h,32h,32h,31h,31h,30h
		DB 30h,2fh,2eh,2dh,2ch,2bh,2ah,29h
		DB 28h,27h,26h,25h,24h,23h,22h,21h
		DB 20h,1fh,1eh,1dh,1ch,1bh,1ah,19h
		DB 18h,17h,16h,15h,14h,13h,12h,11h
		DB 11h,10h,10h,0fh,0fh,0eh,0eh,0dh
		DB 0dh,0dh,0ch,0ch,0ch,0ch,0bh,0bh
		DB 0bh,0bh,0ah,0ah,0ah,0ah,0ah,09h
		DB 09h,09h,09h,09h,09h,09h,09h,09h
		DB 08h,08h,08h,08h,08h,08h,08h,08h
		DB 08h,08h,08h,08h,07h,07h,07h,07h
		DB 07h,07h,07h,06h,06h,06h,06h,06h
		DB 06h,06h,06h,06h,06h,06h,05h,05h
		DB 05h,05h,05h,05h,05h,05h,05h,05h
		DB 04h,04h,04h,04h,04h,04h,04h,04h
		DB 04h,04h,03h,03h,03h,03h,03h,03h
		DB 03h,03h,03h,03h,02h,02h,02h,02h
		DB 02h,02h,02h,02h,02h,01h,01h,01h
		DB 01h,01h,01h,01h,01h,01h,01h,01h

ENDS

END