			Le Pr-processeur
			*****************

1 Inclusion d'un fichier lors de la compilation
***********************************************

	On peut assembler au pralable une routine et l'inclure dans un programme
FORTH au moment de la compilation, en liaison avec COMP.PRG, cecla
donnera un programme monobloc (le fichier est inclus une fois et fait partie de
l'excutable). Il est bien sur possible d'inclure autre chose que du code excutable.
	Pour le code excutable, plutt que de chosir un format objet (de certains
compilateurs) pusiqu'ils ne sont pas tous quivalents, j'ai choisi d'inclure
directement des fichiers xcutables Atari.

>include
--------

	m  >include  "chemin\fichier.ext"

	inclut un fichier  l'intrieur du programme  l'emplacement courant
du dictionnaire. Le mot de commande m est un masque de bits:
	bit 0	: 0=un fichier PRG
		  1=autre
	bit 1	: 0=s'assurer de la parit du pointeur aprs chargement
		  1=ignorer parit
	bit 2    : 0=reloger les adresses absolues
		  1=ne pas reloger

	Voir ci dessous les diffrentes possibilits offertes par cette
commande.

Inclusion d'une routine dans un mot assembl

	Exemple, dans un mot je veux dcaler une valeur de 3 bits vers la
droite (division rapide par 8). Je prpare en assembleur le programme
suivant:

	text

	move.l (a6),d0	; la valeur prise sur la pile
	asr.l #3,d0		; dcale
	move.l d0,(a6)	; remet sur la pile

	end

	Que j'assemble vers C:\DIV8.PRG

	Il ne reste plus qu' crire en FORTH:



:: essai
	p @
	0 >include "C:\DIV8.PRG"
	p !
;

	Ce mot divisera la variable p par 8!

A noter:
	* pas d'espaces dans la chaine du nom de fichier
	* les sections TEXT et DATA sont incluses dans la dfinition,  vous de
'sauter' par dessus les datas si le mot doit se poursuivre.

Inclusion de dfinitions de mots en assembleur

	Si le mot entier doit tre dfinit en assembleur, on doit utiliser une
structure particulire du fichier PRG:
	* la zone TEXT contient les dfinitions et les donnes
	* la zone DATA contient les adresses et les noms des mots crs, elle
est donc rserve.

	Exemple, on peut prparer en assembleur les mots suivants:

	text

plus8:
	dc.w 437		; tous les mots assembls en FORTH commencent
				; par ce code.
	addq.l #8,(a6)	; ajoute 8  la valeur sur la pile
	rts

moins8:
	dc.w 437
	subq.l #8,(a6)	; soustrait 8  la valeur sur la pile
	rts

salut:
	dc.w 437
	lea chaine(pc),a0
	move.l a0,-(a6)	; empile l'adresse d'une chaine
	rts

	dc.w 26		; en FORTH, une chaine est prcde de sa
				; longueur maximale.
chaine: dc.b "Salut, je suis assembl!",0
	even
	data

	dc.b "ADD_DEFS"	; texte obligatoire signalant une srie de
				; dfinitions
	dc.l plus8,moins8,salut,-1
			; suite des adresses et -1 pour terminer
	dc.b "8+",0,"8-",0,"salut",0
			; suite des noms spars par un '0'

	end

	Que j'assemble vers "C:\DEFS.PRG"

	Il suffit d'ajouter dans le programme FORTH:

	0 >include "C:\DEFS.PRG"

	pour disposer des mots '8+',  '8- 'et 'salut'.

A noter:
	* pas d'espaces dans la chaine du nom de fichier
	* seule la zone TEXT est incluse, la zone DATA est simplement lue mais
non conserve.
	* laisser toujours  0 le bit 2 du mot de commande si votre programme
n'est pas relogeable (accs non relatif au PC).

Inclusion 'brute' d'un fichier autre que PRG

	Le problme rside dans la rcupration de l'adresse  laquelle a t
charg le fichier. Le plus simple est d'utiliser l'un des codes internes du
FORTH, il s'agit de [var], utilis dans une variable.
	Une variable est construite ainsi:
	[var]
	+valeur sur 4 octets
	L'action de [var] est de fournir sur la pile l'adresse de la zone qui le
suit immdiatement! Ainsi:

: bloc
	[var]
	1 >include "C:\IMAGE.IMG"
;
	incluera une image dont l'adresse est obtenue en excutant bloc.
Malgr l'utilisation de : ... ; (mode interprt), le mot bloc est parfaitement
assemblable car il est reconnu comme une variable (il commence par [var]!).
	Aucun mot ne sera excut aprs [var] car il contient en lui mme
l'quivalent de ';' (fin de mot).
	Ainsi:

: bloc
	[var]
	1 >include "C:\IMAGE.IMG"
	16 +
;
	ne renverra pas l'adresse de l'image augmente de 16, car la fin du
mot est atteinte avec [var].

En rsum

	* pour inclure un programme le mot de commande est 0
	* pour inclure un autre fichier, le mot de commande est 1
	* si il s'agit d'un programme:
		la section DATA commence par "ADD_DEFS":
			il s'agit d'inclure les dfinitions de la zone TEXT dont les
			adresses et les noms figurent dans la zone DATA.
		la section DATA ne commence pas par "ADD_DEFS":
			il s'agit d'inclure les zones TEXT et DATA comme une
			partie d'une dfinition dj commence.
	* n'utiliser le bit 1 du mot de commande (ignorer parit du dicco) qu'en
connaissance de cause: sur un 68000 les accs mots  une adresse impaire
provoquent une erreur de bus, sur tous les 680X0, une instruction assembleur doit
commencer  une adresse paire.

Pour aller plus loin

	On peut dfinir des variables dans un fichier PRG:

	text

var:
	dc.w 140		; c'est le code de [var]
	dc.l 1234		; la variable est initialise  1234

	data
	dc.b "ADD_DEFS"
	dc.l var,-1
	dc.b "ma_variable",0

	end

	On peut faire du FORTH en assembleur...

	text

forth:
	dc.w 96		; code de 'pad'
	dc.w 92		; code de 'len'
	dc.w 124		; code de '.'
	dc.w 79		; code de ';'

	data
	dc.b "ADD_DEFS"
	dc.l forth,-1
	dc.b "pad_len",0
	end
	Est quivalent :
: pad_len
	pad len .
;
	qui affiche la longueur de la chaine contenue dans pad.

	On peut galement mler dans un mme mot une partie interprte et une
partie assemble:

	text

	move.l (a6)+,d0	; la valeur sur la pile
	btst #0,d0		; le chiffre des units
	beq.s .lb0
	moveq #0,d0		; renvoit 0 si le nombre est impair
	move.l d0,-(a6)
	rts
.lb0:
	moveq #1,d0		; renvoit 1 si il est pair
	move.l d0,-(a6)
	rts

	end

	Assembl vers C:\PAIR.PRG.

	Ensuite:

: parit
	p @ [ass]
	0 >include "C:\PAIR.PRG"
;

	renverra 0 ou 1 selon que la valeur de p est impaire ou paire. De
mme que pour [var], le code [ass] (celui qui vaut 437) contient en lui
mme l'quivalent de ';', ainsi, c'est le dernier mot excut dans parit. On ne
pourra pas appeler parit depuis un mot assembl (puisque le dbut de sa
dfinition est interprte).

Utiliser des variables dfinies en FORTH

	Si la variable est dfinie dans la partie FORTH du programme, il se pose le
problme de fournir son adresse  la partie assembleur si elle doit y accder. Le
plus simple est de dfinir une routine 'init'  qui on donnera ces prcieux
renseignements qui seront sauvs et accessibles aux autres routines:

	text

init:
	dc.w 437
	lea adresses(pc),a0
	move.l (a6)+,(a0)+	 ; rcupre deux adresses et les range
	move.l (a6)+,(a0)+
	rts

adresses: dc.l 0,0		; place pour deux adresses: une variable et pad

majusc:
	dc.w 437
	lea adresses(pc),a0
	move.l (a0)+,a1	; adresse de la variable
	move.l (a0)+,a2	; adresse de pad
	move.l (a6)+,a0	; adresse d'une chaine
	move.l a2,-(a6)	; renvoit pad sur la pile
	moveq #0,d1		; 0 caractres au dpart
.lb0:
	move.b (a0)+,d0	; un caractre
	beq.s	.lb1		; si nul, fin de chaine
	addq.w #1,d1	; compte
	and.b #$DF,d0	; en majuscule
	move.b d0,(a2)+	; dans pad
	bra.s .lb0		; continuer
.lb1:
	move.l d1,(a1)	; longueur de chaine renvoye dans la variable
	rts

	data
	dc.b "ADD_DEFS"
	dc.l init,majusc,-1
	dc.b "init",0,"majusc",0

	end

	Assembl vers "C:\DEFS.PRG".

	Ainsi:

variable Longueur

0 >include "C:\DEFS.PRG"

>comp

pad Longueur init	\ permet au mot 'majusc' de tourner correctement

" Coucou" majusc	\ renvoit sur la pile pad contenant "COUCOU" et la
			\ longueur 6 dans la variable Longueur.



2 Prparer le source assembleur sous l'Editeur
***********************************************

	Pour faciliter la mise au point d'un programme, le texte assembleur
peut-tre crit sous l'diteur FORTH, export et assembl lors de la compilation:

>export
-------

	m >export "chemin\fichier.ext"
	....
	>comp

	Le mot >export permet d'envoyer dans un fichier texte toutes les
lignes le suivant jusqu'au prochain >comp (qui doit tre le premier mot de
sa ligne!) Le mot de commande m ne contient que la valeur du flag (voir
>true et >false).

3 Utilisation d'un assembleur extrieur
***************************************

	Une fois le code tap siour l'diteur et export, il peut tre assembl
directement  partir du FORTH lors de la compilation, c'est le mot >exec qui se
charge d'appeler l'assembleur.

>exec
-----

	m >exec "chemin\prog.ext"
	"ligne de commande"

	excute le programme spcifi en lui transmettant la ligne de
commande (qui se trouve obligatoirement sur la ligne suivante).
	le mot m:
	bit 0	: 0=appui d'une touche aprs l'excution du programme
		   1=ne pas attendre
	bit 1	: 0=ERREUR si le programme renvoit une valeur positive
		   1=ne pas signaler d'erreur
	bit 2	: 0=ERREUR si le programme renvoit une valeur ngative
		   1=ne pas signaler d'erreur
	bit 3	: 0=fermer la fentre FORTH le temps de l'excution
		   1=ne pas tenir compte de la fentre

	Dans tous les cas, une valeur nulle renvoye par l'assembleur ne
gnre pas d'erreur. La rgle voudrait que seules les valeurs ngatives
correspondent  des erreurs, mais certains programmes renvoient un code
positif. Ainsi, les bits 1 et 2 permettent de s'adapter  toutes les situations.
	En cas d'attente de touche (bit 0 = 0), l'appui sur 'ESC' interrompt le
traitement comme une erreur.




4 Compilation conditionnelle, les Flags
***************************************

	Si on compile plusieurs fois de suite un programme FORTH sans avoir
modifi les parties exportes, il est inutile de les re-exporter et de les re-assembler
avec les commandes >export et >exec.
	Ainsi, on dispose d'une compilation conditionnelle rudimentaire, mais
suffisante. Le mot de commande 'm' des trois instructions >export, >exec,
>include, peut contenir le numro d'un flag  tester pour valider ou ignorer
l'action. Ce flag est signal dans le mot suprieur (bits 16  31) de 'm':

>true
-----
	n  >true  : valide le flag n (de 1  15). Au dmarrage, tous les flags
sont 'vrais' par dfaut.

>false
------
	n >false  : invalide le flag n (de 1  15).

exemples:
	%h40000 >export "f:\test.s"

	n'exportera que si le flag 4 est vrai. En prenant l'oppos de 'm', on ne
valide l'opration que si le flag est faux:

	%h-20008 >exec "F:\assemble\asm.ttp"
	"f:\test.s"

	n'assemble que si le flag 2 est faux, le 8 correspond au bit 3, ne pas
fermer la fentre FORTH lors de l'excution.

5 Autres Liens Extrieurs
*************************

	On peut trs bien exporter autre chose que de l'asembleur, excuter autre
chose que ASM.TTP. On peut imaginer qu'un programme FORTH ait besoin
d'une image calcule par POV:

	0 >export "F:\POV\image.pov"	\ envoit le script sur disque
	...
	ici se trouve le script de l'image
	>comp

	0 >exec "F:\POV\pov30_82.ttp"	\ calcule l'image
	"-iIMAGE.POV -oIMAGE.TGA +w100 +h100" \ en 100x100

	: image
		[var]
		0 >include "F:\POV\IMAGE.TGA"	\ l'inclut au programme!
	;

	Le mot image dposera alors l'adresse du fichier en RAM.