	TITLE	SOUND.ASM


	PAGE   ,132



;***************************************************************************
;*									   *
;*	SOUND_AS.ASM : assembly functions for digitized sound		   *
;*									   *
;*	(c) Herv‚ Soulard, Version 1.0 - 10/01/1991                        *
;*	                   Version 1.1 - 01/02/1991                        *
;*									   *
;***************************************************************************



	.MODEL	SMALL


;---------------------------------------------------------------------------
;
;	Definition des constantes.
;
;---------------------------------------------------------------------------


EOI		EQU	20h		; Commande de fin d'interruption

PIT_CTRL	EQU	43h		; Port de controle du PIT
PIT_HP		EQU	42h		; Port de donnees du canal HP
PIT_CLOCK	EQU	40h		; Port de donnees du canal CLOCK

PPI_CTRL	EQU	61h		; Port de controle du PPI

CTRL_HP_1	EQU	090h		; Valeur de controle debut son
CTRL_HP_2	EQU	0B6h		; Valeur de controle fin son

DATA_HP		EQU	0533h		; Donnee pour fin son

CTRL_CLK	EQU	34h		; Valeur de controle CLOCK

HP_ON		EQU	03h		; Donnee pour HP actif
HP_OFF		EQU	0FCh		; Donnee pour HP inactif


sound		STRUC			; Sound structure
ident		DB	32 DUP (?)	; identificator of sound file
buffer		DD	?		; buffer for sampled values
nbValues	DD	?		; nb of sampled values
hertz		DW	?		; 
timer		DB	?		; value for It timer
mult		DB	?		; value of mult. freq.
memo		DB	255 DUP (?)	; comment for sound
sound		ENDS



	.DATA


		PUBLIC	_soundDone
_soundDone	DB	1		; le son est termine ?

values		DD	?		

multMain	DB	?
multAux		DB	?


	.CODE


oldInt08	DD	?

normClk		DW	?		; appeler l'ancienne int 08
tmp		DW	?		; tout les combien ?




;---------------------------------------------------------------------------
;
;	Le son est joue par l'interruption horloge (frequence = hertz).
;
;---------------------------------------------------------------------------



;------ Interruption horloge.
;
;

New_08	PROC	FAR

	pushf
	push	ax
	push	bx
	push	cx
	push	si
	push	ds
	push	es

	mov	al, 20h
	out	20h, al

	mov	ax, DGROUP
	mov	ds, ax

	les	si, dword ptr values	; Pointeur sur les donnees
	mov	al, byte ptr es:[si]	; al = nouvelle donnee
	or	al, al
	jz	n1			; Fin des donnees ?

n4:
	dec	byte ptr multAux
	jnz	n3

	mov	ah, byte ptr multMain
	mov	byte ptr multAux, ah

	inc	si			; prochaine donnee

n3:
	out	PIT_HP, al

	jnz	n2			; fin des premiers 64Ko ?

	mov	ax, 1000h
	add	word ptr values + 2, ax	; segment suivant

n2:
	mov	word ptr values, si	; Mise a jour pointeur
	jmp	fin
	
n1:
	cli				; Fini de jouer, on remet tout

	mov	al, CTRL_HP_2		; Initialisation du son a 0
	out	PIT_CTRL, al
	mov	ax, DATA_HP
	out	PIT_HP, al
	mov	al, ah
	out	PIT_HP, al

	mov	al, CTRL_CLK		; Initialisation de la frequence
	out	PIT_CTRL, al		; d'horloge
	mov	al, 0
	out	PIT_CLOCK, al
	out	PIT_CLOCK, al

	in	al, PPI_CTRL		; HP inactif
	and	al, HP_OFF
	out	PPI_CTRL, al

	mov	byte ptr _soundDone, 1	; fin du son

	les	bx, dword ptr cs:oldInt08
	xor	ax, ax
	mov	ds, ax
	mov	word ptr ds:[20h], bx	; remet l'interruption 08
	mov	word ptr ds:[22h], es
	
fin:
	pop	es
	pop	ds
	pop	si
	pop	cx
	pop	bx

	dec	word ptr cs:tmp
	jnz	fin1
	
	mov	ax, word ptr cs:normClk
	mov	word ptr cs:tmp, ax
	pop	ax
	popf
	jmp	dword ptr cs:oldInt08

fin1:
	pop	ax
	popf

	iret


New_08	ENDP



;---------------------------------------------------------------------------
;
;	Fonctions. 
;
;---------------------------------------------------------------------------


;---------------------------------------------------------------------------
;
;	playSound :
;
;		plays the sound contains in the buffer precised
;		by the parameter.
;
;		initializes the interrupt 8 to the New_08 function
;		and prepares HP port to receive digitized sound.
;
;
;	interface :
;
;		int playSound(struct sound sSound)
;


	PUBLIC	_playSound

_playSound	PROC

	push	bp
	mov	bp, sp

arg	EQU	<[BP+04h]>

	push	di
	push	es

	cmp	byte ptr _soundDone, 1
	jz	e2
	
	mov	ax, 0
	jmp	e1

e2:
	mov	byte ptr _soundDone, 0

	les	di, arg.buffer
	mov	word ptr values, di
	mov	ax, es
	mov	word ptr values+2, ax

	mov	ax, 10
	mul	arg.hertz
	mov	cx, 182
	div	cx
	mov	word ptr cs:normClk, ax
	mov	word ptr cs:tmp, ax

	mov	al, arg.mult
	mov	byte ptr multMain, al
	mov	byte ptr multAux, al


	push	ds
	pop	es

	cli

	xor	ax, ax
	mov	es, ax
	les	bx, dword ptr es:[20h]	; Sauvegarde le vecteur It CLK
	mov	word ptr cs:oldInt08, bx
	mov	word ptr cs:oldInt08 + 2, es

	mov	es, ax
	mov	ax, OFFSET New_08	; Nouvelle interruption CLK
	mov	word ptr es:[20h], ax
	mov	ax, cs
	mov	word ptr es:[22h], ax
	
	mov	al, CTRL_HP_2		; Initialisation du son a 0
	out	PIT_CTRL, al
	mov	al, 0
	out	PIT_HP, al
	out	PIT_HP, al

	mov	al, CTRL_CLK		; Initialisation de la frequence
	out	PIT_CTRL, al		; d'horloge
	mov	al, arg.timer
	out	PIT_CLOCK, al
	mov	al, 0
	out	PIT_CLOCK, al

	mov	al, CTRL_HP_1		; Prepare le canal HP a recevoir
	out	PIT_CTRL, al    	; de nouvelles frequence

	in	al, PPI_CTRL		; HP actif
	or	al, HP_ON
	out	PPI_CTRL, al
	
	sti

	mov	ax, 1
e1:
	pop	es
	pop	di

	mov	sp, bp
	pop	bp

	ret


_playSound	ENDP


	END
