	Salut Godefroy,

	Les annotations de prsentation sont incluses entre crochets, et
il n'y a que l qu'on trouve des crochets d'ailleurs.
	[TEXTE] -> dbut d'une zone normale, tu formates au kilomtre
	[LISTING] -> dbut d'une zone de programme ASM, a afficher avec
		l'allure d'un listing.
	[DP] -> dbut de paragraphe forc, en gros, commencer une nouvelle
		ligne.

	Guillaume


[TEXTE]

	PROGRAMMER LES 8 TIMERS DU TT (1)
	*********************************

	Le TT apporte 4 timers de plus que les autres modles
(chronomtres dclanchant une routine  intervalles rguliers et
programmables). Sur un ST, les 4 timers sont grs par le MFP 68901,
composant qui s'occupe galement du port parallle. Le TT possde tout
simplement deux MFPs.

Fonctionnement d'un Timer
-------------------------

	La frquence de base des MFP est 2,4576MHz: les seules autres
frquences qu'on peut utiliser s'obtiennent par division de cette
frquence de base: c'est  dire que toutes sont des sous-multiples de
2,4576MHz.

	Pour programmer un Timer  une certaine cadence, il faut donc
trouver la meilleure division pour s'approcher de la valeur souhaite,
j'expliquerai dans le paragraphe suivant comment s'y prendre. Lorsque ce
diviseur est trouv, il suffit de remplir correctement les registres du
MFP et le Timer se lance: il excutera votre routine  la frquence
programme.

	Il va sans dire que l'assembleur est le meilleur choix, en effet,
il faut perturber le moins possible le systme. Ce langage vous assure une
totale maitrise de la sauvegarde des regsitres du CPU (car votre routine
va s'excuter en meme temps que le systme continue de tourner) et une
vitesse maximale ( 10KHz, votre routine s'excute 10000 fois par
seconde!) pour ne pas trop ralentir l'ensemble de la machine.

Registres CONTROL et DATA d'une frquence
-----------------------------------------

	Pour mieux suivre les explications de ce paragraphe, il n'est pas
inutile de se munir d'une calculatrice pour refaire les calculs.
	Reprenons nos divisions: supposons que ma frquence voulue soit
FV=1325Hz. A partir de la frquence de base FB=2,4576MHz, je peux dire
que FB/FV=1855 en arrondissant  l'entier. A cause de l'arrondi, j'aurai
en fait FB/1855=1324,8Hz, ce qui est trs proche. Il suffirait d'indiquer
au systme: "prdivise par 1855 avant de lancer le timer". Mais a n'est
pas aussi simple...
	Nous ne pouvons pas indiquer n'importe quel diviseur au MFP, il
faut qu'il soit multiple de 4 ou 10, 16, 50, 64, 100 ou 200. Ceci est la
liste des valeurs possibles qu'on choisit par l'intermdiare du registre
CONTROL d'un Timer (voir fig.1). Voyons comment on peut s'approcher de
1855 avec ces donnes:
[DP]	4*464=1856
[DP]	10*185=1850 ou 10*186=1860
[DP]	16*116=1856
[DP]	50*37=1850
[DP]	64*29=1856
[DP]	100*19=1900
[DP]	200*9=1800
[DP]	Ds la premire ligne, la meilleure valeur est obtenue, mais... il
y a encore une limitation: le 464 ne tient pas sur un octet, nous sommes
limits aux entiers compris entre 1 et 255! Ceci constitue la valeur
associe au registre DATA du Timer. Ne pouvant pas utiliser 4*464, nous
n'avons ensuite que l'embarras du choix entre le multiple de 16 et celui de
64.
	Exemple, avec 16*116=1856, la frquence relle est:
[DP]	FR1=FB/1856=1324,1Hz
[DP]	Mais, selon les applications on pourra lui prfrer une valeur par
excs avec 10*185=1850, la frquence relle est:
[DP]	FR2=FB/1850=1328,4Hz
[DP]	Avec FR2>FV, votre routine s'excutera un peu plus souvent que
voulu, avec FR1<FV, elle s'excutera un peu moins souvent.

	Connaissant les limites de CONTROL et DATA, nous pouvons obtenir
les frquences maximales et minimales que peut gnrer un MFP. On obtient la
frquence maximale et prenant le diviseur minimal: c'est  dire:
[DP]	CONTROL=1, DATA=1, FMAX=FB/(4*1)=614,4KHz
[DP]	La frquence minimale s'obtient en prenant le diviseur maximal:
[DP]	CONTROL=7, DATA=255, FMIN=FB/(200x255)=482Hz.

[DP]	Bon, sur un STE  8MHz, il ne faut certainement pas esprer faire
tourner un Timer  614,4KHz d'autant que l'instruction RTE qui met fin 
une routine d'interruption prend  elle seule 20 cycles d'horloge!!!
	Il ne faut pas croire non plus qu'on s'approchera facilement de
n'importe quelle valeur entre 482 et 614400: la seule frquence qu'on
peut obtenir en dessous de FMAX est avec CONTROL=1 et DATA=2, ce qui nous
donne 307200 Hz, ensuite, c'est avec CONTROL=2 et DATA=1 qui donne 245760
Hz. Voyez que dans les hautes frquences il y a de grandes plages vides.

Enfin, on se lance!
-------------------
	Le gros des prparatifs est fait, voici le programme gnral pour
dclancher l'un des 8 timers. Certaines constantes diffrent selon les
Timers, ces valeurs sont regroupes dans les figures 2 et 3:

[LISTING]

	; execute la routine
	; "lancer" en superviseur

	pea lancer
	move #38,-(sp)
	trap #14
	addq.l #6,sp
	....

lancer:
	move.l #BASE,a0
	move sr,-(sp)
	or #$700,sr
	bclr #NB,VALID(a0)
	bclr #NB,VALID+12(a0)
	move.b #data,DAT(a0)
	move.b #control,CONT(a0) (1)
	move.l #routine,ROUT  (2)
	bclr #3,23(a0)
	bset #NB,VALID(a0)
	bset #NB,VALID+12(a0)
	move (sp)+,sr
	rts

[TEXTE]

Remarques:
	(1) pour les Timers C et D, cette instruction doit etre remplace
car ces deux timers partagent le meme octet pour le registre CONTROL, l'un
dans les bits 0-3, l'autre dans les bits 4-7:

[LISTING]
	; pour Timer C:

	and.b #$0F,CONT(a0)
	move.b #control,d0
	lsl.b #4,d0
	or.b d0,CONT(a0)

	; pour Timer D:

	and.b #$F0,CONT(a0)
	or.b #control,CONT(a0)

[TEXTE]
	(2) Si on utilise le MFP TT, il faut alors utiliser:

[LISTING]
	move.l #routine,ROUT+64

[TEXTE]
Mais, il faut savoir s'arreter...
---------------------------------

	On utilise le meme principe, la fonction 38 du XBIOS permet de
lancer une routine en superviseur:

[LISTING]
	pea stopper
	move #38,-(sp)
	trap #14
	addq.l #6,sp
	...

stopper:
	move.l #BASE,a0
	move sr,-(sp)
	or #$700,sr
	bclr #NB,VALID(a0)
	bclr #NB,VALID+4(a0)
	bclr #NB,VALID+8(a0)
	bclr #NB,VALID+12(a0)
	move (sp)+,sr
	rts

[TEXTE]
La routine proprement dite
--------------------------

	C'est le coeur de la chose: le petit bout de programme qui sera
excut  la frquence de votre choix. Trois impratifs: sauver TOUS les
registres utiliss, finir avec un RTE, optimiser tant que possible.
	Deux exemples, d'abord un chrono au millime de seconde:
[DP]	CONTROL=2 et DATA=246 -> FR=FB/(10*246)=999 Hz, presque 1000...

[LISTING]
routine:
	addq.l #1,compteur
	rte
compteur: dc.l 0

[TEXTE]
	Autre exemple, la lecture d'un son 25KHz sur une ST Replay 16. Le
son est en 16 bits mono:
[DP]	CONTROL=1 et DATA=25 -> FR=FB/(4*25)=24576Hz

[LISTING]
routine:
	move.l a0,-(sp)
	move.l pointeur(pc),a0
	move $FB0000,(a0)+
	move.l a0,pointeur
	move.l (sp)+,a0
	rte
pointeur: dc.l zone
zone: dc.l 24576*2*nombre de secondes  enregistrer

[TEXTE]

Limites
-------
	Rptons les limites lies  la frquence voulue:
[DP]	- on n'en obtient souvent qu'une valeur approche
[DP]	- plus la frquence est leve, plus le systme sera ralenti
	jusqu' etre compltement bloqu au dela d'un certain seuil.

[DP]	Viennent ensuite les limites de disponibilit des Timers, en effet
le systme en utilise  son propre compte (voir fig 4). Dans la pratique,
seront toujours libres les Timers A du MFP ST et B du MFP TT. Les deux
Timers D et le Timer C du MFP TT sont libres si vous ne faites pas usage
de vos ports srie. Quand au Timer A du MFP TT qui est signal comme
"rserv"... sur ma machine il est libre! Atari avait certainement des
projets qui n'ont plus raison d'etre aujourd'hui.

	L'article n'a pas abord l'utilisation possible des timers A et B
en tant que compteur d'vnements, ou en synchronisation avec une horloge
externe. Je n'ai jamais utilis moi meme ces possibilits, alors je ne m'y
risquerai pas!

	Nous voil arrivs  la fin, la prochaine fois je donnerai, en GFA
par exemple, l'algorithme pour calculer automatiquement les valeurs
CONTROL et DATA pour une frquence donne: ce langage tant simple, vous
n'aurez pas de mal  l'adapter au votre!

	Guillaume Tello
	gtello@wanadoo.fr