Initial commit
authorFrancois Fleuret <francois@fleuret.org>
Sat, 24 Aug 2013 15:26:18 +0000 (17:26 +0200)
committerFrancois Fleuret <francois@fleuret.org>
Sat, 24 Aug 2013 15:26:18 +0000 (17:26 +0200)
Turmites [new file with mode: 0644]
Turmites.TXT [new file with mode: 0644]
Turmites.s [new file with mode: 0644]

diff --git a/Turmites b/Turmites
new file mode 100644 (file)
index 0000000..ba5de7a
Binary files /dev/null and b/Turmites differ
diff --git a/Turmites.TXT b/Turmites.TXT
new file mode 100644 (file)
index 0000000..77e250b
--- /dev/null
@@ -0,0 +1,23 @@
+
+ Les commandes au clavier sont :
+
+  A  Nutrition automatique
+  P  Pause
+  I  Informations
+ 1-2-3-4 Changement de couleur de nourriture
+  Q  Quitter
+  R  Reset (repart avec turmite actuelle)
+  F  Suivre la turmite sélectionnée
+  T  Mode tuer
+  S  Mode sélection
+  M  Mémorise l'image actuelle
+ f1-f2-f3-f4 Reconstruit le terrain en blocs
+ f5  Remplie le terrain
+ f6  Ramène l'image memorisée
+
+ La nutrition automatique ramène automatiquement l'image sauvée
+ avec la commande "M" toutes les 15 secondes; cela permet de laisser
+ les turmites vivre sans avoir à les nourrir constamment.
+                                               François Fleuret
+                                               Juillet 1990
diff --git a/Turmites.s b/Turmites.s
new file mode 100644 (file)
index 0000000..6bf1e24
--- /dev/null
@@ -0,0 +1,1435 @@
+
+;      TURMITES  (c) F.Fleuret 28/11/89
+;              version assembleur AMIGA
+
+; opt d+                       ; option d'assemblage (sauve les labels)
+
+ExecBase=4
+
+OldOpenLibrary=-408
+CloseLibrary=-414
+Forbid=-132
+AllocMem=-198
+FreeMem=-210
+FindTask=-294
+WaitPort=-384
+GetMsg=-372
+ReplyMsg=-378
+
+DisplayAlert   equ     -90
+
+pr_CLI=$AC
+pr_MsgPort=$5C
+
+Frequence      =       500
+
+ntur   equ     1024    ; nombre maximum de turmites
+
+X      equ     0       ; abscisse
+Y      equ     2       ; ordonnée
+E      equ     4       ; état
+O      equ     6       ; orientation
+V      equ     8       ; niveau d'énergie
+Table  equ     10      ; table de comportement
+
+ndatas equ     58
+
+Startup:
+       sub.l   a1,a1
+       move.l  ExecBase,a6
+       jsr     FindTask(a6)
+       move.l  d0,a2
+       tst.l   pr_CLI(a2)
+       bne.s   FromCLI
+
+       lea     pr_MsgPort(a2),a0
+       jsr     WaitPort(a6)
+       lea     pr_MsgPort(a2),a0
+       jsr     GetMsg(a6)
+       move.l  d0,WBMsg
+
+FromCLI:
+
+;      On réserve de la mémoire en CHIP-RAM pour les bitplanes,
+;      les sprites et la copper-list. (l'ami Thomas va etre heureux !)
+
+       move.l  ExecBase,a6
+       move.l  #$8000*4+256*8+32*2,d0
+       move.l  #$10002,d1      ; CHIP et CLEAR
+       jsr     AllocMem(a6)
+
+       move.l  d0,plan1                ; premier bitplan
+       beq     alerte          ; si pas de chip reservée !
+       add.l   #$8000,d0
+       move.l  d0,plan2                ; second bitplan
+       add.l   #$8000,d0
+       move.l  d0,SaveImage    ; zone de sauvegarde
+       add.l   #$10000,d0
+       move.l  d0,copper_list  ; copper-list
+       add.l   #256,d0
+       move.l  d0,SpriteCursor ; et les sprites
+       add.l   #256,d0
+       move.l  d0,SpriteVide
+       add.l   #256,d0
+       move.l  d0,SpriteSelect
+       add.l   #256,d0
+       move.l  d0,SpriteTableau
+       add.l   #1024,d0
+       move.l  d0,SpriteNombre
+
+       bsr     main            ; LA routine
+
+;      On rend la mémoire
+
+       move.l  ExecBase,a6
+       move.l  plan1,a1
+       move.l  #$8000*4+256*8+32*2,d0
+       jsr     FreeMem(a6)
+
+EmergencyReturn:
+       move.l  WBMsg(pc),d0
+       beq.s   More
+       move.l  d0,a1
+       jsr     Forbid(a6)
+       jsr     ReplyMsg(a6)
+More:
+       moveq   #0,d0
+       rts
+
+WBMsg: dc.l    0
+
+
+alerte:
+       lea     IntuitionName(pc),a1
+       move.l  (ExecBase).w,a6
+       jsr     OldOpenLibrary(a6)
+       move.l  d0,a6
+
+       lea     TexteAlerte(pc),a0
+       moveq   #0,d0
+       move.l  #32,d1
+       jsr     DisplayAlert(a6)
+
+       move.l  a6,a1
+       move.l  (ExecBase).w,a6
+       jsr     CloseLibrary(a6)
+       bra     EmergencyReturn
+
+TexteAlerte:
+       dc.b    0,32,18," Turmites meditation: pas assez de CHIP ! ",0,0
+       even
+
+
+;      ************************************************************
+;      ************************************************************
+;      *************  Voila le coeur du programme !!! *************
+;      ************************************************************
+;      ************************************************************
+
+main:
+
+       bsr     save_all                ; sauve tout pour pouvoir revenir
+       bsr     Inits           ; initialise les registres hard
+
+       lea     TableAdan,a1    ; copie le tableau de la première turmite
+       bsr     BigStart
+       clr.w   FlagQuit
+
+MainBoucle:
+
+       clr.w   VblFlag
+       bsr     turmites
+synchro:
+       tst.w   VblFlag
+       beq     synchro
+
+       bsr     AfficheNombre   ; routine pour afficher le nombre de turmites
+       bsr     GetKey          ; routine de lecture clavier
+       tst.w   d0
+       bmi     pasdetouche
+       tst.b   d0              ; si appuie et pas relache, on ne fait rien
+       bmi     pasdetouche
+       and.w   #$7f,d0
+
+;      A               Nutrition automatique
+;      P               Pause
+;      I               Informations
+;      1-2-3-4         Changement de couleur de nourriture
+;      Q               Quitter
+;      R               Reset (repart avec turmite actuelle)
+;      F               Suivre la turmite sélectionnée
+;      T               Mode tuer
+;      S               Mode sélection
+;      M               Mémorise l'image actuelle
+;      f1-f2-f3-f4     Reconstruit terrain en blocs
+;      f5              Remplie le terrain
+;      f6              Ramène l'image sauvée
+
+       cmp.w   #$10,d0         ; "A"
+       bne     PasAuto
+       not.w   FlagAuto
+       eor.b   #2,$bfe001
+PasAuto:
+
+       cmp.w   #$21,d0         ; "S"
+       bne     PasModeSelection
+       move.w  #-1,ModeDroite
+       move.l  SpriteCursor,a0
+       lea     ImageCursor,a1
+       bsr     InitSprites     ; copie les données bitmap du sprite 'selection'
+PasModeSelection:
+
+       cmp.w   #$14,d0         ; "T"
+       bne     PasModeTuer
+       clr.w   ModeDroite
+       move.l  SpriteCursor,a0
+       lea     ImageTuer,a1
+       bsr     InitSprites     ; copie les données bitmap du sprite 'tuer'
+PasModeTuer:
+
+       cmp.w   #$23,d0         ; "F"
+       bne     PasSuivre
+       not.w   FlagSuivre      ; commute le flag
+       bra     ApresKeys
+PasSuivre:
+
+       cmp.w   #$55,d0         ; "f6"
+       bne     Pasf6
+       bsr     AfficheImage
+       bra     ApresKeys
+Pasf6:
+
+       cmp.w   #$29,d0         ; "M"
+       bne     PasRameneImage
+       move.l  plan1,a0
+       move.l  SaveImage,a1
+       move.w  #16383,d0
+RameneImage:
+       move.l  (a0)+,(a1)+
+       dbf     d0,RameneImage
+       bra     ApresKeys
+PasRameneImage:
+
+       cmp.w   #$50,d0         ; "f1" à "f4"
+       bmi     Pasfx
+       cmp.w   #$54,d0
+       bpl     Pasfx
+       sub.w   #$50-5,d0
+       move.w  #1,d1
+       lsl.w   d0,d1
+       move.w  d1,d0
+       bsr     DrawWorld       ; redessine le terrain
+       bra     ApresKeys
+Pasfx:
+
+       cmp.w   #$54,d0         ; "f5"
+       bne     Pasf5
+       bsr     ClearWorld      ; vide avec la couleur en cours
+       bra     ApresKeys
+Pasf5:
+
+       cmp.b   #$19,d0         ; "P"
+       bne     PasPause
+       not.w   FlagPause       ; commute le flag
+       bra     ApresKeys
+PasPause:
+
+       cmp.b   #$20,d0         ;"Q"
+       bne     PasQuit
+       move.w  #-1,FlagQuit    ; personnellement, je suis contre, mais
+       bra     ApresKeys       ; les meilleurs choses ont une fin...
+PasQuit:
+
+       move.w  d0,d1           ; "1" à "4"
+       sub.w   #1,d1
+       bmi     PasColors
+       cmp.w   #4,d1
+       bpl     PasColors
+       move.w  d1,Color        ; change la couleur en cours
+       add.w   d1,d1
+       move.w  CouleursSouris(pc,d1.w),$dff180+18*2
+       bra     ApresKeys
+CouleursSouris:
+       dc.w    $000,$f00,$00f,$ec0     ; noir, rouge, bleu, jaune.
+PasColors:
+
+       cmp.w   #$17,d0         ; "I"
+       bne     PasAffiche
+       bsr     ClearTableau
+       not.w   FlagAffiche     ; commute le flag de l'affichage
+       tst.w   FlagAffiche
+       beq     ApresKeys
+       bsr     AfficheCerveau  ; si mode affiche
+       bra     ApresKeys
+PasAffiche:
+
+       cmp.w   #$13,d0         ; "R"
+       bne     PasReset
+       tst.w   nombre
+       beq     ResetComplet    ; si toutes mortes, on repart du début
+       tst.l   AdrSelect
+       beq     PasReset
+       move.l  AdrSelect,a1
+       lea     Table(a1),a1
+       bsr     BigStart        ; reprend au début
+       bra     ApresKeys
+ResetComplet:
+       lea     TableAdan,a1    ; copie le tableau de la première turmite
+       bsr     BigStart
+       bra     ApresKeys
+PasReset:
+
+ApresKeys:
+pasdetouche:
+
+       tst.w   FlagAuto
+       beq     PasDejeuner
+       add.w   #1,CompteurFreq
+       cmp.w   #Frequence,CompteurFreq
+       bne     PasDejeuner
+       bsr     AfficheImage
+       clr.w   CompteurFreq
+PasDejeuner:
+       
+
+       btst    #6,$bfe001      ; test de la touche gauche de la souris
+       bne     PasMouseKey
+       bsr     Paves           ; routine qui affiche la nourriture
+PasMouseKey:
+
+       tst.w   FlagAffiche     ; le mode affichage y-est-il ?
+       beq     PasNouveau
+       move.l  AdrSelect,d0
+       cmp.l   PAdrSelect,d0   ; la turmite a-t-elle changé ?
+       beq     PasNouveau
+       move.l  AdrSelect,PAdrSelect    ; mémorise la nouvelle turmite
+       bsr     AfficheCerveau
+PasNouveau:
+
+       tst.w   FlagQuit                ; veut-on quitter ?
+       beq     MainBoucle
+
+       and.b   #253,$bfe001
+       bsr     restore_all     ; remet tout en place
+       moveq   #0,d0           ; et revient
+       rts
+
+VblFlag:       dc.w    0       ; flag de synchronisation VBL
+ModeDroite:    dc.w    -1      ; role du bouton droit souris (select/tuer)
+FlagAuto:      dc.w    0       ; flag pour la nutrition auto.
+CompteurFreq:  dc.w    0       ; Compteur pour la nutrition
+FlagPause:     dc.w    0       ; flag pour le mode pause
+FlagSuivre:    dc.w    0       ; flag pour 'follow'
+FlagQuit:      dc.w    0       ; flag pour quitter
+FlagAffiche:   dc.w    0       ; flag pour l'affichage du tableau
+PAdrSelect:    dc.l    0       ; turmite actuellement affichée
+Color:         dc.w    2       ; couleur de la nourriture actuelle
+
+
+;      **********************************************************
+;      ********* Affichage du nombre de turmites à l'écran ******
+;      **********************************************************
+
+AfficheNombre:
+       move.w  nombre,d0
+       lea     TableCarChiffres,a4     ; table des caractères numériques
+       divu    #10,d0          ; utilise le reste d'une division par 10
+       swap    d0
+       lsl.w   #4,d0
+       lea     (a4,d0.w),a1
+       clr.w   d0
+       swap    d0
+       divu    #10,d0
+       swap    d0
+       lsl.w   #4,d0
+       lea     (a4,d0.w),a2
+       clr.w   d0
+       swap    d0
+       divu    #10,d0
+       swap    d0
+       lsl.w   #4,d0
+       lea     (a4,d0.w),a3
+       clr.w   d0
+       swap    d0
+       divu    #10,d0
+       swap    d0
+       lsl.w   #4,d0
+       lea     (a4,d0.w),a4
+
+       move.l  SpriteNombre,a0         ; adresse des datas de ce sprite
+       lea     4(a0),a0                ; datas bitmap
+       move.w  #5,d0                   ; caractères de 6 lignes
+BoucleAfficheNombre:           ; recopie les caractères de la table
+       move.w  (a4)+,d1                ; dans le sprite.
+       lsl.w   #5,d1
+       or.w    (a3)+,d1
+       move.w  d1,(a0)
+       clr.w   2(a0)
+       move.w  (a2)+,d1
+       lsl.w   #5,d1
+       or.w    (a1)+,d1
+       lsl.w   #6,d1
+       move.w  d1,32(a0)
+       clr.w   34(a0)
+       add.l   #4,a0
+       dbf     d0,BoucleAfficheNombre
+       rts
+
+
+;      **********************************************************
+;      *** Routine d'initialisation de la table des turmites ****
+;      **********************************************************
+
+BigStart:
+       lea     DataTurmites,a0
+       lea     AdressesLibres,a5       ; constitue la table des adresses libres
+       move.w  #ntur-1,d0
+RempliePile:
+       clr.w   V(a0)
+       move.l  a0,-(a5)
+       add.l   #ndatas,a0
+       dbf     d0,RempliePile
+
+       move.l  (a5)+,a0        ; initialise la première turmite
+       move.l  a5,SPtur
+       move.w  #255,X(a0)
+       move.w  #255,Y(a0)
+       move.w  #0,E(a0)
+       move.w  #0,O(a0)
+       move.w  #1,V(a0)
+       lea     Table(a0),a0
+       move.w  #(ndatas-Table)/2-1,d0
+BoucleBigStart:
+       move.w  (a1)+,(a0)+
+       dbf     d0,BoucleBigStart
+
+       move.w  #256,d0
+       bsr     DrawWorld               ; affiche le décors avec un bloc central de 256
+
+       clr.l   AdrSelect       ; on vire la sélection et l'affichage
+       clr.w   FlagAffiche
+       bsr     ClearTableau
+
+       rts
+
+;      **********************************************************
+;      ******* Routine d'affichage des paves de nourriture ******
+;      **********************************************************
+
+Paves:
+       move.w  Xmousew,d0      ; si on dépasse à droite alors on corrige
+       cmp.w   #498,d0
+       bmi     PasPavesDroite
+       move.w  #497,d0
+PasPavesDroite:
+       move.w  d0,d4
+       and.w   #$0f,d4         ; masque pour le décalage
+       move.w  Ymousew,d1
+       cmp.w   #497,d1         ; test le dépassement en bas
+       bmi     PasPavesBas
+       move.w  #496,d1
+PasPavesBas:
+                       ; calcul de l'adresse en mémoire vidéo
+       lsl.w   #6,d1           ; 64 octets par ligne (512 points)
+       lsr.w   #3,d0           ; on divise X par 8
+       and.w   #$fffe,d0       ; force une adresse paire
+       add.w   d1,d0           ; X+Y
+       move.l  plan1,a0        ; + base de la mémoire
+       lea     (a0,d0),a0
+       move.l  plan2,a1        ; idem plan 2
+       lea     (a1,d0),a1
+
+       move.l  #$ffff0000,d0   ; dessin du bloc
+       lsr.l   d4,d0           ; avec décalage
+       not.l   d0              ; et masque
+
+       move.w  Color,d1
+       clr.l   d2              ; dessin pour le plan 1
+       clr.l   d3              ; dessin pour le plan 2
+
+               ; on modifie d2 et d3 en fonction des bits de la couleur
+       btst    #0,d1
+       beq     PasPlan0
+       move.l  d0,d2
+       not.l   d2
+PasPlan0:
+       btst    #1,d1
+       beq     PasPlan1
+       move.l  d0,d3
+       not.l   d3
+PasPlan1:
+
+       move.w  #15,d4  ; blocs de 16 lignes de haut
+BouclePaves:
+       and.l   d0,(a0)
+       or.l    d2,(a0)
+       add.l   #64,a0
+       and.l   d0,(a1)
+       or.l    d3,(a1)
+       add.l   #64,a1
+       dbf     d4,BouclePaves
+FinPaves:
+       rts
+
+;      **********************************************************
+;      *********** Routine d'affichage d'un 'Cerveau' ***********
+;      **********************************************************
+
+AfficheCerveau:
+       movem.l d0-a6,-(sp)
+       tst.l   AdrSelect       ; y a-t-il une turmite sélectionnée ?
+       beq     PasCerveau              ; si non, alors ne rien faire
+
+       move.l  SpriteTableau,a0        ; sprite pour afficher le tableau
+       lea     4(a0),a0                ; adresse des données bitmap du sprite
+       move.l  AdrSelect,a1    ; adresse de la turmite sélectionnée
+       lea     Table(a1),a1    ; adresse de son tableau de comportement
+       move.w  #3,d0           ; 4 états
+BoucleEtat:
+       move.w  #3,d1           ; et 4 couleurs par état
+BoucleCouleur:
+       move.b  (a1)+,d3
+       add.b   #1,d3
+       ext.w   d3
+       lsl.w   #4,d3
+       lea     TableCarDirections,a2   ; table des caractères (g/a/d)
+       lea     (a2,d3.w),a2
+       move.b  (a1)+,d3
+       ext.w   d3
+       lsl.w   #4,d3
+       lea     TableCarEtats,a3                ; table des caractères états (A/B/C/D)
+       lea     (a3,d3.w),a3
+       move.b  (a1)+,d3
+       ext.w   d3
+       lsl.w   #4,d3
+       lea     TableCarChiffres,a4     ; chiffres (0/1/2/3...)
+       lea     (a4,d3.w),a4
+
+       move.w  #5,d2
+BoucleCar:
+       moveq   #0,d3
+       or.w    (a2)+,d3
+       or.w    (a3)+,d3
+       or.w    (a4)+,d3
+       move.w  d3,(a0)+
+       clr.w   (a0)+
+       dbf     d2,BoucleCar
+       add.w   #256-24,a0
+       dbf     d1,BoucleCouleur
+       add.w   #28-256*4,a0
+       dbf     d0,BoucleEtat
+
+PasCerveau:
+       movem.l (sp)+,d0-a6
+       rts
+
+ClearTableau:          ; vide la bitmap du sprite tableau
+       movem.l d0/a0,-(sp)
+       move.l  SpriteTableau,a0
+       lea     4(a0),a0
+       move.w  #55,d0
+BoucleClearTableau:
+       clr.w   256(a0)
+       clr.w   512(a0)
+       clr.w   768(a0)
+       clr.w   (a0)+
+       dbf     d0,BoucleClearTableau
+       movem.l (sp)+,d0/a0
+       rts
+
+;      **********************************************************
+;      **** Routine de gestion des déplacements des turmites ****
+;      **********************************************************
+
+nombre:        dc.w    0
+
+turmites:
+       clr.w   nombre          ; vide le nombre
+       lea     DataTurmites,a0 ; tableau des turmites
+       move.l  SPtur,a5        ; pile des adresses libres
+       move.l  plan1,a4        ; base mémoire vidéo plan 1
+       move.l  plan2,a3        ; base mémoire vidéo plan 2
+       move.l  #ntur-1,d0      ; nombre de turmites
+boucle:
+
+       tst.w   V(a0)           ; est-elle en vie ?
+       beq     finboucle               ; si non, sniff...
+
+       add.w   #1,nombre       ; une de plus en vie !
+
+       move.w  X(a0),d1
+       move.w  Y(a0),d2
+
+       move.w  Xmousew,d3      ; est-elle sous la souris ?
+       sub.w   d1,d3
+       bpl     PasAbs1
+       neg.w   d3
+PasAbs1:
+       cmp.w   #8,d3
+       bpl     PasSousMouse
+
+       move.w  Ymousew,d3
+       sub.w   d2,d3
+       bpl     PasAbs2
+       neg.w   d3
+PasAbs2:
+       cmp.w   #8,d3
+       bpl     PasSousMouse
+       btst    #10,$dff016     ; POTGOR
+       bne     PasSousMouse
+
+;                      elle est sous la souris
+
+       tst.w   ModeDroite
+       beq     ModeTuer
+ModeSelection:         ; si mode sélection, mémorise son adresse
+       move.l  a0,AdrSelect
+       bra     PasSousMouse
+ModeTuer:
+       clr.w   V(a0)           ; si mode tuer, on la desintègre
+       move.l  a0,-(a5)        ; nouvelle adresse libre dans la pile
+       cmp.l   AdrSelect,a0    ; si c'était elle qui était sélectionnée
+       bne     finboucle
+       clr.l   AdrSelect       ; elle ne l'est plus
+       clr.w   FlagSuivre      ; le mode follow dégage
+       clr.w   FlagAffiche     ; le tableau disparait
+       bsr     ClearTableau    ; il faut l'effacer
+       bra     finboucle
+PasSousMouse:
+
+       tst.w   FlagPause       ; est-on en mode pause
+       bne     finboucle               ; si oui, on ne fait pas les mouvements
+
+       move.w  d1,d3           ; si non
+       lsl.w   #6,d2
+       lsr.w   #3,d3
+       add.w   d3,d2           ; d2 adr dans le bitplan
+       not.w   d1
+       and.w   #7,d1
+
+       moveq   #0,d3           ; d3 couleur de la case sous la turmite
+       btst    d1,(a4,d2.w)    ; on test les bits en mémoire vidéo
+       beq     bit0nul
+       or.w    #1,d3
+bit0nul:
+       btst    d1,(a3,d2.w)
+       beq     bit1nul
+       or.w    #2,d3
+bit1nul:
+       add.w   d3,V(a0)
+
+; calcul de l'adresse de la case dans le tableau de comportement
+
+       move.w  d3,d4           ; d3=d3*3 (pour la colonne, 3 octets par case)
+       add.w   d3,d3
+       add.w   d4,d3
+
+       move.w  E(a0),d4        ; d4=état*12 (pour la ligne, 12 octets par ligne)
+       add.w   d4,d4
+       add.w   d4,d4
+       add.w   d4,d3
+       add.w   d4,d4
+       add.w   d4,d3
+       move.w  d3,d4
+
+       lea     Table(a0,d4),a1
+       move.b  1(a1),E+1(a0)   ; nouvel état
+       move.b  0(a1),d3
+       add.b   d3,O+1(a0)
+       and.b   #3,O+1(a0)      ; nouvelle direction
+       moveq   #0,d3
+       move.b  2(a1),d3        ; couleur à mettre sous la turmite avant de partir
+
+bit0d:                 ; le plot pour afficher la turmite
+       btst    #0,d3           ; surement optimisable...
+       beq     bit0dnul
+bit0dnnul:
+       bset    d1,(a4,d2.w)
+       bra     bit1d
+bit0dnul:
+       bclr    d1,(a4,d2.w)
+bit1d:
+       btst    #1,d3
+       beq     bit1dnul
+bit1dnnul:
+       bset    d1,(a3,d2.w)
+       bra     finbitd
+bit1dnul:
+       bclr    d1,(a3,d2.w)
+finbitd:
+
+PasPlot:
+       sub.w   #1,V(a0)                ; elle se fatigue
+       sub.w   d3,V(a0)                ; et perd la valeur de ce qu'elle met sur la case
+       bgt     PasMorte                ; est-elle morte de fatigue ?
+Morte:
+       clr.w   V(a0)           ; la vie est dure au pays des turmites
+       move.l  a0,-(a5)        ; nouvelle adresse libre dans la pile
+       cmp.l   AdrSelect,a0    ; si c'était elle qui était sélectionnée
+       bne     finboucle
+       clr.l   AdrSelect       ; elle ne l'est plus
+       clr.w   FlagSuivre      ; le mode follow dégage
+       clr.w   FlagAffiche     ; le tableau disparait
+       bsr     ClearTableau    ; il faut l'effacer
+       bra     finboucle
+PasMorte:
+       move.w  O(a0),d1        ; sinon, mouvement
+       btst    #0,d1
+       bne     DeplaceHoriz
+
+DeplaceVert:
+       btst    #1,d1
+       bne     Monte
+       add.w   #1,Y(a0)
+       and.w   #511,Y(a0)      ; limite à 512 points en hauteur
+       bra     FinDeplace
+Monte:
+       sub.w   #1,Y(a0)
+       and.w   #511,Y(a0)
+       bra     FinDeplace
+
+DeplaceHoriz:
+       btst    #1,d1
+       bne     Gauche
+       add.w   #1,X(a0)
+       and.w   #511,X(a0)      ; limite à 512 points en largeur
+       bra     FinDeplace
+Gauche:
+       sub.w   #1,X(a0)
+       and.w   #511,X(a0)
+
+FinDeplace:
+       cmp.w   #128,V(a0)      ; a-t-elle suffisament d'énergie pour se reproduire ?
+       bmi     finboucle               ; non
+Duplique:
+       lsr.w   V(a0)           ; elle perd de l'énergie
+       cmp.l   #AdressesLibres,a5              ; y-a-t-il de la place ?
+       beq     finboucle                       ; non...
+
+       move.l  (a5),a1
+
+       move.l  a0,a2
+       rept    ndatas/2        ; recopie son tableau dans son descendant
+       move.w  (a2)+,(a1)+
+       endr
+
+       move.l  (a5)+,a2
+
+;              **** Mutations ****
+
+       move.w  #3,d6
+aleatoire:
+               ; d3 et d4 = random(256)
+
+       move.w  CompteurRnd,d4
+       add.l   #$87654321,d4
+       move.l  d4,d5
+       add.l   d5,d5
+       add.l   d5,d4
+       move.l  d4,CompteurRnd
+
+       move.w  CompteurRnd,d3
+       add.l   #$87654321,d3
+       move.l  d3,d5
+       add.l   d5,d5
+       add.l   d5,d3
+       move.l  d3,CompteurRnd
+
+       move.w  d4,d5
+       lsr.w   #2,d5
+       and.w   #15,d5  ; 16 cases possibles dans le tableau
+       move.w  d5,d1   ; *3 car 3 octets par case
+       add.w   d5,d5
+       add.w   d1,d5
+       lea     Table(a2,d5.w),a1
+
+       and.w   #3,d4
+       cmp.w   #1,d4   ; modifie-t-on la direction ?
+       bne     PasDir  ; si non...
+ChercheRnd3:
+       move.w  CompteurRnd,d3
+       add.l   #$87654321,d3
+       move.l  d3,d5
+       add.l   d5,d5
+       add.l   d5,d3
+       move.l  d3,CompteurRnd
+       and.w   #3,d3
+       cmp.w   #3,d3
+       beq     ChercheRnd3
+       move.b  rnd3(pc,d3),0(a1)
+       bra     finaleatoire
+rnd3:  dc.b    -1,0,1,0
+PasDir:
+       and.w   #3,d3   ; modifie-t-on l'état ?
+       cmp.w   #2,d4   ; si non...
+       bne     PasEta
+       move.b  d3,1(a1)
+       bra     finaleatoire
+PasEta:
+       cmp.w   #3,d4   ; modifie-t-on la couleur ?
+       bne     aleatoire       ; si non, on revient au début
+       move.b  d3,2(a1)
+finaleatoire:
+       dbf     d6,aleatoire    ; et on fait ça 4 fois
+
+finboucle:
+
+       add.l   #ndatas,a0      ; turmite suivante
+       dbf     d0,boucle
+       move.l  a5,SPtur        ; sauve le nouveau pointeur
+       rts
+
+CompteurRnd:   dc.l    0
+AdrSelect:     dc.l    0
+
+;      ******************************************************
+;      *********** Routine de traçage du terrain ************
+;      ******************************************************
+
+;      D0=Largeur du coté (32/64/128/256)
+
+DrawWorld:
+       movem.l d0-a6,-(sp)
+
+       move.l  plan1,a0        ; bases des bitplanes
+       move.l  plan2,a1
+       moveq   #0,d1
+       moveq   #0,d2
+       move.w  #$1fff,d3       ; tout d'abord, on efface
+ClearScreen:
+       move.l  d1,(a0)+
+       move.l  d2,(a1)+
+       dbf     d3,ClearScreen
+
+       move.w  d0,d1           ; calcul de l'adresse de début, on passe
+       move.w  d0,d2           ; des octets pour la marge de gauche.
+       lsl.w   #5,d1
+       lsr.w   #4,d2
+       add.w   d2,d1
+       move.l  plan1,a0
+       move.l  plan2,a1
+       add.w   d1,a0
+       add.w   d1,a1
+
+       bsr     ChoixBits               ; voire ci-dessous
+
+       move.l  #512,d3         ; combien de carrés ?
+       divu    d0,d3           ; un DIVU ne peut pas faire de mal
+       lsr.w   #1,d3           ; (enfin, pas trop de mal...)
+       sub.w   #1,d3
+       move.w  d3,a2
+
+       move.w  d0,d3
+       sub.w   #1,d3
+       move.w  d3,a3
+
+       move.w  d0,d6
+       lsr.w   #4,d6
+       sub.w   #1,d6
+       lsl.w   #6,d0
+
+       move.w  a2,d4           ; boucle verticale des carrés
+DWboucleV:
+       move.w  a2,d5           ; idem horizontale
+DWboucleH:
+
+       move.w  a3,d3           ; les boucles pour UN carré
+DWpetiteboucleV:
+       move.w  d6,d7
+DWpetiteboucleHfill:
+       move.w  d1,(a0)+
+       move.w  d2,(a1)+
+       dbf     d7,DWpetiteboucleHfill
+       move.w  d6,d7
+DWpetiteboucleHclear:
+       clr.w   (a0)+
+       clr.w   (a1)+
+       dbf     d7,DWpetiteboucleHclear
+       dbf     d3,DWpetiteboucleV
+
+       dbf     d5,DWboucleH
+       add.w   d0,a0
+       add.w   d0,a1
+       dbf     d4,DWboucleV
+       movem.l (sp)+,d0-a6
+       rts
+
+
+ClearWorld:            ; remplie l'écran avec la couleur en cours
+       movem.l d0-a6,-(sp)
+       move.l  plan1,a0
+       move.l  plan2,a1
+       bsr     ChoixBits
+       move.w  #$3fff,d3
+ClearScreen2:
+       move.w  d1,(a0)+
+       move.w  d2,(a1)+
+       dbf     d3,ClearScreen2
+       movem.l (sp)+,d0-a6
+       rts
+
+
+
+AfficheImage:
+       move.l  SaveImage,a0
+       move.l  plan1,a1
+       move.w  #16383,d0
+SauveImage:
+       move.l  (a0)+,(a1)+
+       dbf     d0,SauveImage
+       rts
+
+
+ChoixBits:             ; la routine qui détermine les mots en
+       moveq   #0,d1           ; fonction des bits de la couleur
+       moveq   #0,d2
+       move.w  Color,d3
+       btst    #0,d3
+       beq     PasCls0
+       move.w  #-1,d1
+PasCls0:
+       btst    #1,d3
+       beq     PasCls1
+       move.w  #-1,d2
+PasCls1:
+       rts
+
+
+;      ******************************************************
+;      ******************* Initialisations ******************
+;      ******************************************************
+
+Inits:
+       lea     $dff000,a6
+
+       move.w  #$7fff,$9a(a6)          ; INTENA
+       move.w  #$7fff,$96(a6)          ; DMACON
+       move.w  #$c020,$9a(a6)          ; IT vbl uniquement
+       move.w  #$83a0,$96(a6)          ; copper et bitplan
+
+       move.l  SpriteVide,a0
+       clr.l   (a0)+
+       clr.l   (a0)+
+
+       move.l  SpriteTableau,a0        ; positionne les sprites
+       move.w  #$2e50,(a0)
+       move.w  #$4a00,2(a0)
+       move.w  #$2e58,256(a0)
+       move.w  #$4a00,256+2(a0)
+       move.w  #$2e60,512(a0)
+       move.w  #$4a00,512+2(a0)
+       move.w  #$2e68,768(a0)
+       move.w  #$4a00,768+2(a0)
+
+       move.l  SpriteNombre,a0
+       move.w  #$2ec2,(a0)
+       move.w  #$3400,2(a0)
+       move.w  #$2eca,32(a0)
+       move.w  #$3400,34(a0)
+
+       move.l  SpriteCursor,a0
+       lea     ImageCursor,a1
+       bsr     InitSprites
+       move.l  SpriteSelect,a0
+       lea     ImageSelect,a1
+       bsr     InitSprites
+
+       move.l  copper_list,a0
+
+       move.l  #$00e00000,(a0)+        ; la copper-list met les pointeurs
+       move.l  #$00e20000,(a0)+        ; bitplanes
+       move.l  #$00e40000,(a0)+
+       move.l  #$00e60000,(a0)+
+       move.l  #$01020000,(a0)+
+       move.l  #$fffffffe,(a0)+
+
+; On se met en 256*256 2 bitplanes (4 couleurs) avec 16 points cachés
+; sur la gauche pour pouvoir faire un scrolling avec le delay.
+
+       move.l  copper_list,$80(a6)     ; COP1LC
+       clr.w   $88(a6)                 ; COPJMP1
+       move.l  #$2ca12ca1,$8e(a6)      ; DIWSTRT et DIWSTOP
+       move.w  #$2200,$100(a6)         ; BPLCON0
+       clr.l   $102(a6)                        ; BPLCON1 et BPLCON2
+       move.w  #30,$108(a6)            ; BPLMOD1
+       move.w  #30,$10a(a6)            ; BPLMOD2
+       move.l  #$004000c0,$92(a6)      ; DDFSTRT et DDFSTOP
+
+       move.l  #irq,$6c                ; vecteur irq
+
+       move.w  #$0024,$dff104          ; priorité des sprites
+       move.w  #$555,$dff180+17*2      ; couleurs de ces meme sprites
+       move.w  #$00f,$dff180+18*2
+       move.w  #$fff,$dff180+19*2
+       move.w  #$fff,$dff180+21*2
+       move.w  #$fff,$dff180+25*2
+       move.w  #$fff,$dff180+29*2
+
+       clr.w   $dff180                 ; couleur playfield
+       move.w  #$f00,$dff182           ; noir, rouge, bleu, jaune
+       move.w  #$00f,$dff184
+       move.w  #$ec0,$dff186
+       bsr     InitClavier             ; initialise le clavier
+
+       rts
+
+InitSprites
+       move.w  #15,d0
+       clr.l   (a0)+
+RecopieSprites:
+       move.l  (a1)+,(a0)+
+       dbf     d0,RecopieSprites
+       clr.l   (a0)+
+       rts
+
+;      ********************************************************
+;      ******************* Gestion de la souris ***************
+;      ********************************************************
+
+Souris:
+       move.b  $dff00a,d1      ; abscisse souris (absolue) JOY0DAT
+       move.b  d1,d3
+       move.b  $dff00b,d0      ; ordonnée souris (absolue) JOY0DAT
+       move.b  d0,d2
+
+       sub.b   PrecXmouse,d0   ; - précédente abscisse= déplacement relatif
+       cmp.b   #127,d0         ; > 127, c'est que l'on a fait un tour complet
+       bmi     OkXmouse
+       add.b   #255,d0         ; on corrige
+OkXmouse:
+
+       sub.b   PrecYmouse,d1   ; idem pour l'ordonnée
+       cmp.b   #127,d1
+       bmi     OkYmouse
+       add.b   #255,d1
+OkYmouse:
+
+       ext.w   d0              ; passage en .W (relatif, peut etre négatif)
+       ext.w   d1
+       move.b  d3,PrecYmouse   ; nouvelle coordonnées absolues du système
+       move.b  d2,PrecXmouse
+       add.w   d0,Xmouse       ; ajoute le mouvement relatif aux coordonnées du
+       add.w   d1,Ymouse       ; programme (qui sont absolues)
+
+       cmp.w   #255,Xmouse     ; dépasse-t-on à droite ?
+       bmi     PasMouseDroite
+       move.w  Xmouse,d0       ; si oui, on déplace la fenetre
+       move.w  #255,Xmouse     ; et on remet la valeur maximum
+       sub.w   #255,d0
+       add.w   d0,Xwindow
+       bra     PasMouseGauche
+PasMouseDroite:
+       tst.w   Xmouse          ; dépasse-t-on à gauche ?
+       bpl     PasMouseGauche
+       move.w  Xmouse,d0       ; si oui, on déplace aussi la fenetre
+       clr.w   Xmouse          ; et on met la valeur minimum
+       add.w   d0,Xwindow
+PasMouseGauche:
+       cmp.w   #255,Ymouse     ; idem pour Y
+       bmi     PasMouseBas
+       move.w  Ymouse,d0
+       move.w  #255,Ymouse
+       sub.w   #255,d0
+       add.w   d0,Ywindow
+       bra     PasMouseHaut
+PasMouseBas:
+       tst.w   Ymouse
+       bpl     PasMouseHaut
+       move.w  Ymouse,d0
+       clr.w   Ymouse
+       add.w   d0,Ywindow
+PasMouseHaut:
+
+       move.w  Xmouse,d0
+       move.w  Ymouse,d1
+       add.w   #$a0,d0         ; coordonnées translatées dans le cadre écran
+       add.w   #$2c,d1
+
+       move.w  d1,d2
+       add.w   #8,d2           ; Y du bas du sprite
+
+       move.w  d0,d3           ; calcul des deux mots de controle en fonction
+       lsr.w   #1,d3           ; de HSTART, VSTART et VSTOP
+       move.w  d1,d4
+       lsl.w   #8,d4
+       move.b  d3,d4
+
+       move.b  d2,d5
+       lsl.w   #8,d5
+       roxl.w  #8,d1
+       roxl.b  #1,d5
+       roxl.w  #8,d2
+       roxl.b  #1,d5
+       roxr.b  #1,d0
+       roxl.b  #1,d5
+
+       move.l  SpriteCursor,a0 ; met en place les deux mots de controle
+       move.w  d4,(a0)+
+       move.w  d5,(a0)
+
+       rts
+
+ImageCursor:
+       dc.w    $ff00,$fe00     ; une petit flèche 8*8
+       dc.w    $8200,$fc00
+       dc.w    $8400,$f800
+       dc.w    $8800,$f000
+       dc.w    $9000,$e000
+       dc.w    $a000,$c000
+       dc.w    $c000,$8000
+       dc.w    $8000,$0000
+ImageTuer:
+       dc.w    $ff00,$ff00     ; un petit carré 8*8
+       dc.w    $8100,$fe00
+       dc.w    $bd00,$c200
+       dc.w    $a500,$c600
+       dc.w    $a500,$c600
+       dc.w    $bd00,$de00
+       dc.w    $8100,$fe00
+       dc.w    $ff00,$8000
+ImageSelect:
+       dc.w    $d800,$d800     ; une petite mire 8*8
+       dc.w    $8800,$8800
+       dc.w    $0000,$0000
+       dc.w    $8800,$8800
+       dc.w    $d800,$d800
+       dc.w    $0000,$0000
+       dc.w    $0000,$0000
+       dc.w    $0000,$0000
+
+Xmouse:                dc.w    256
+Ymouse:                dc.w    256
+PrecXmouse:    dc.w    0
+PrecYmouse:    dc.w    0
+Xwindow:       dc.w    128
+Ywindow:       dc.w    128
+Xmousew:       dc.w    384
+Ymousew:       dc.w    384
+
+;      ******************************************************
+;      ***************  Routine du 'scrolling' **************
+;      ******************************************************
+
+Screen:
+       tst.w   FlagSuivre      ; est-on-en mode suivie automatique ?
+       beq     PasSuivie               ; non
+       tst.l   AdrSelect       ; une turmite est-elle sélectionnée ?
+       beq     PasSuivie               ; non
+       move.l  AdrSelect,a0    ; si oui
+       tst.w   V(a0)           ; est-elle vivante ?
+       beq     PasSuivie               ; non
+PasFinSuivre:
+       move.w  X(a0),d0        ; prend ses coordonnées
+       sub.w   #128,d0         ; centre
+       move.w  d0,Xwindow      ; et les met dans celles de la fenetre
+       move.w  Y(a0),d0
+       sub.w   #128,d0
+       move.w  d0,Ywindow
+PasSuivie:
+
+       move.w  Xwindow,d0      ; on corrige éventuellement les
+       bpl     PasWindowGauche ; coordonnées de la fenetre
+       moveq   #0,d0
+       move.w  d0,Xwindow
+       bra     PasWindowDroite
+PasWindowGauche:
+       cmp.w   #256,d0
+       bmi     PasWindowDroite
+       move.w  #256,d0
+       move.w  d0,Xwindow
+PasWindowDroite:
+       move.w  Ywindow,d1
+       bpl     PasWindowHaut
+       moveq   #0,d1
+       move.w  d1,Ywindow
+       bra     PasWindowBas
+PasWindowHaut:
+       cmp.w   #256,d1
+       bmi     PasWindowBas
+       move.w  #256,d1
+       move.w  d1,Ywindow
+PasWindowBas:
+
+       move.w  Xmouse,Xmousew  ; coordonnées absolues de la souris dans
+       add.w   d0,Xmousew      ; le terrain
+       move.w  Ymouse,Ymousew
+       add.w   d1,Ymousew
+
+       lsl.w   #6,d1           ; calcule de l'adresse de départ des bitplanes
+       move.w  d0,d2
+       lsr.w   #3,d2
+       and.w   #$fffe,d2
+       add.w   d2,d1
+       not.w   d0
+       and.w   #15,d0
+       moveq   #0,d2
+       move.w  d0,d2
+       lsl.w   #4,d0
+       or.w    d0,d2
+
+       move.l  copper_list,a1  ; met le delay dans la copper-list
+       move.w  d2,2+16(a1)
+
+       move.l  plan1,a0
+       add.w   d1,a0
+       move.l  a0,d0
+
+       move.w  d0,6(a1)        ; met l'adresse dans la copper-list
+       swap    d0
+       move.w  d0,2(a1)
+       swap    d0
+
+       add.l   #$8000,d0       ; deuxième bitplan
+       move.w  d0,6+8(a1)
+       swap    d0
+       move.w  d0,2+8(a1)
+
+       moveq   #0,d4           ; gestion du sprite curseur de sélection
+       moveq   #0,d5
+       move.l  AdrSelect,d0
+       beq     PasSpriteSelection
+       move.l  d0,a0
+       tst.w   V(a0)
+       beq     PasSpriteSelection
+       move.w  X(a0),d0
+       sub.w   Xwindow,d0
+       bmi     PasSpriteSelection
+       cmp.w   #255,d0
+       bpl     PasSpriteSelection
+       move.w  Y(a0),d1
+       sub.w   Ywindow,d1
+       bmi     PasSpriteSelection
+       cmp.w   #255,d1
+       bpl     PasSpriteSelection
+
+       add.w   #$9d,d0         ; pareil que pour celui de la souris
+       add.w   #$2a,d1
+
+       move.w  d1,d2
+       add.w   #8,d2
+
+       move.w  d0,d3
+       lsr.w   #1,d3
+       move.w  d1,d4
+       lsl.w   #8,d4
+       move.b  d3,d4
+
+       move.b  d2,d5
+       lsl.w   #8,d5
+       roxl.w  #8,d1
+       roxl.b  #1,d5
+       roxl.w  #8,d2
+       roxl.b  #1,d5
+       roxr.b  #1,d0
+       roxl.b  #1,d5
+
+PasSpriteSelection:
+       move.l  SpriteSelect,a0
+       move.w  d4,(a0)+
+       move.w  d5,(a0)
+
+       rts
+
+
+;      ******************************************************
+;      ****************** Routines de l'IRQ *****************
+;      ******************************************************
+
+irq:
+       movem.l d0-a6,-(sp)
+       bsr     GereSprites
+       bsr     Souris
+       bsr     Screen
+       move.w  #-1,VblFlag
+       movem.l (sp)+,d0-a6
+       move.w  #$20,$dff09c            ; it vbl traitée INTREQ
+       rte
+
+;      ******************************************************
+;      ***** Routine de gestion des sprites (début VBL) *****
+;      ******************************************************
+
+GereSprites:
+       move.l  SpriteCursor,$dff120    ; SPR0PT
+       move.l  SpriteSelect,$dff124    ; SPR1PT
+       move.l  SpriteNombre,d0
+       move.l  d0,$dff128              ; SPR2PT
+       add.l   #32,d0
+       move.l  d0,$dff12c              ; SPR3PT
+       move.l  SpriteTableau,d0        ; 4 sprites pour le tableau
+       move.l  d0,$dff130              ; SPR4PT
+       add.l   #256,d0
+       move.l  d0,$dff134              ; SPR5PT
+       add.l   #256,d0
+       move.l  d0,$dff138              ; SPR6PT
+       add.l   #256,d0
+       move.l  d0,$dff13c              ; SPR7PT
+       rts
+
+;      ******************************************************
+;      **************** Routines du clavier *****************
+;      ******************************************************
+
+InitClavier:
+       clr.w   PointeurClavierRead     ; vide les pointeurs du tampon
+       move.w  #1,PointeurClavierWrite
+       lea     ItClavier(pc),a0                ; en PC-relatif !
+       move.l  a0,$68                  ; vecteur niveau 2 (clavier)
+       move.b  #%10001000,$bfed01      ; ICR, bit SP (fin de transfert série)
+       move.w  #$8008,$dff09a          ; INTENA (IT CIA-A)
+       rts
+
+ItClavier:
+       movem.l a0/d0/d1,-(sp)
+       move.w  $dff01e,d0              ; INTREQ (read: IT CIA-A ?)
+       btst    #3,d0
+       beq     FinItClavier
+
+       move.b  $bfed01,d0
+       btst    #3,d0                   ; pas clavier
+       beq     PasClavier
+       move.w  PointeurClavierWrite,d1
+       moveq   #0,d0
+       move.b  $bfec01,d0
+       or.b    #$40,$bfee01
+       not.b   d0
+       ror.b   #1,d0
+       add.b   #1,d1
+       cmp.w   PointeurClavierRead,d1
+       beq     TamponClavierSature
+       lea     TamponClavier(pc),a0
+       move.b  d0,(a0,d1.w)
+       move.w  d1,PointeurClavierWrite
+TamponClavierSature:
+       and.b   #$bf,$bfee01
+PasClavier:
+       move.w  #$0008,$dff09c          ; INTREQ (IT traitée)
+FinItClavier:
+       movem.l (sp)+,a0/d0/d1
+       rte
+
+GetKey:
+       moveq   #0,d0
+       move.l  d1,-(sp)
+       move.w  PointeurClavierRead,d1  ; pointeur relatif sur le tampon
+       add.b   #1,d1                   ; touche suivante
+       cmp.w   PointeurClavierWrite,d1 ; a-t-on vidé le tampon ?
+       beq     NoKey
+       move.b  TamponClavier(pc,d1.w),d0       ; si non, on remet le code
+       move.w  d1,PointeurClavierRead  ; sauve le pointeur
+       move.l  (sp)+,d1                ; et on revient
+       rts
+NoKey:
+       not.w   d0                      ; code d'erreur -1
+       move.l  (sp)+,d1
+       rts
+
+PointeurClavierRead:   dc.w    0
+PointeurClavierWrite:  dc.w    0
+TamponClavier:         ds.b    256
+
+
+save_all:
+       move.b  #%10000111,$bfd100
+       move.l  4,a6
+       jsr     -132(a6)
+       move.l  $68,save_vecteur_kbd
+       move.l  $6c,save_vecteur_irq
+       move.w  $dff01c,save_intena     ; INTENA (read)
+       or.w    #$c000,save_intena
+       move.w  $dff002,save_dmacon     ; DMACON (read)
+       or.w    #$8100,save_dmacon
+       rts
+
+restore_all:
+       move.w  #$7fff,$dff09a          ; INTENA (write: clear all)
+       move.w  #$7fff,$dff096          ; DMACON (write: clear all)
+       move.l  save_vecteur_kbd,$68    ; vecteur IT clavier
+       move.l  save_vecteur_irq,$6c    ; vecteur IT vbl
+       move.w  save_intena,$dff09a     ; INTENA (write: remet les bits)
+       move.w  save_dmacon,$dff096     ; DMACON (write: remet les bits)
+       move.l  4,a6
+       lea     GraphicName,a1
+       jsr     OldOpenLibrary(a6)
+       move.l  d0,a0
+       move.l  38(a0),$dff080          ; COP1LC
+       clr.w   $dff088                 ; COPJMP1
+       move.l  d0,a1
+       jsr     CloseLibrary(a6)
+       rts
+
+save_intena:   dc.w    0
+save_dmacon:   dc.w    0
+save_vecteur_irq:      dc.l    0
+save_vecteur_kbd:      dc.l    0
+
+GraphicName:   dc.b    "graphics.library",0
+DosName:       dc.b    "dos.library",0
+IntuitionName: dc.b    "intuition.library",0
+
+       even
+
+;      Table des caractères
+
+TableCarDirections:
+       dc.w    $0000,$0400,$0C00,$1C00,$0C00,$0400,0,0
+       dc.w    $0000,$1800,$1800,$1800,$1800,$1800,0,0
+       dc.w    $0000,$2000,$3000,$3800,$3000,$2000,0,0
+TableCarEtats:
+       dc.w    $00C0,$0120,$0120,$01E0,$0120,$0120,0,0
+       dc.w    $01C0,$0120,$01C0,$0120,$0120,$01C0,0,0
+       dc.w    $00E0,$0100,$0100,$0100,$0100,$00E0,0,0
+       dc.w    $01C0,$0120,$0120,$0120,$0120,$01C0,0,0
+TableCarChiffres:
+       dc.w    $0006,$0009,$0009,$0009,$0009,$0006,0,0
+       dc.w    $0002,$0006,$000A,$0002,$0002,$0002,0,0
+       dc.w    $0006,$0009,$0001,$0002,$0004,$000F,0,0
+       dc.w    $0006,$0009,$0002,$0001,$0009,$0006,0,0
+       dc.w    $0008,$0008,$000A,$000F,$0002,$0002,0,0
+       dc.w    $000F,$0008,$000E,$0001,$0001,$000E,0,0
+       dc.w    $0007,$0008,$000E,$0009,$0009,$0006,0,0
+       dc.w    $000F,$0001,$0001,$0002,$0002,$0002,0,0
+       dc.w    $0006,$0009,$0006,$0009,$0009,$0006,0,0
+       dc.w    $0006,$0009,$0009,$0007,$0001,$000E,0,0
+
+A      equ     0
+B      equ     1
+C      equ     2
+D      equ     3
+
+g      equ     -1
+a      equ     0
+d      equ     1
+
+;      turmite de départ
+
+TableAdan:
+       dc.b    d,B,1,a,A,0,a,B,0,a,B,0
+       dc.b    a,B,0,a,A,0,d,C,0,a,A,0
+       dc.b    a,B,0,a,A,0,a,D,0,a,A,0
+       dc.b    a,B,0,a,A,0,g,A,0,a,A,0
+
+Copyrights:
+       dc.b    " Ecrit par F.Fleuret, Novembre 1989 "  ; je suis toujours possessif
+
+       section data1,bss
+startbss:
+       ds.l    ntur            ; Pile des adresses libres
+AdressesLibres:
+SPtur: ds.l    1
+plan1:         ds.l    1               ; pointeurs pour la CHIP-RAM réservée
+plan2:         ds.l    1               ;  Le Devpac se plante (et si !) si il
+SaveImage:     ds.l    1               ; y a des DC.x dans le segment BSS
+copper_list:   ds.l    1
+SpriteCursor:  ds.l    1
+SpriteSelect:  ds.l    1
+SpriteTableau: ds.l    1
+SpriteVide:    ds.l    1
+SpriteNombre:  ds.l    1
+
+       section data2,bss
+
+DataTurmites:
+       ds.w    ndatas/2*ntur
+
+       end