Obligement - L'Amiga au maximum

Jeudi 25 avril 2024 - 07:00  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in english


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : La technique de programmation par overlays
(Article écrit par Denis Jarril et extrait d'Amiga News Tech - novembre 1991)


La technique de programmation par "overlays" permet de disposer d'une application de plusieurs centaines de kilo-octets sur disque mais en utilisant beaucoup moins en mémoire centrale.

Comment ça marche ?

C'est très simple, tout du moins dans la théorie : on ne charge les routines en mémoire qu'au fur et à mesure de leur utilisation, et on les libère lorsqu'elles se terminent. Vous vous doutez certainement que pratiquement, c'est plus compliqué : une routine du programme principal doit s'occuper de libérer et de charger les nouveaux overlays au moment opportun. Fort heureusement, le compilateur Lattice Lc et son éditeur de liens associé BLink réduisent au strict minimum le travail du programmeur : celui-ci n'a plus qu'à simplement prévoir quelles fonctions de son application seront ou ne seront pas des overlays. Avouez que c'est déjà quand même plus simple.

Une représentation classique des overlays est sous forme d'arborescence, comme dans la figure 1 ci-dessous.

overlays
Figure 1

La racine est le programme principal, le premier à être chargé. Quoiqu'il arrive, il réside toujours en mémoire et ne pourra pas en être viré par le gestionnaire d'overlays.

Les overlay 1 et overlay 2 s'exécutent indépendamment l'un de l'autre, un seul à la fois : le programme principal ne peut pas appeler de fonctions de l'overlay 1 puis de l'overlay 2 sans que le gestionnaire ne le charge d'abord. De cet arbre, quelques règles simplissimes découlent :
  • Si l'overlay 1 est chargé, les 2, 3, 4 et 5 ne le sont pas.
  • Si l'overlay 2 est chargé, le 1 ne l'est pas, mais 3, 4 et 5 peuvent l'être (ce n'est pas obligatoire).
  • Si l'overlay 3 est chargé, le 2 l'est aussi, les 1 et 4 ne le sont pas, et le 5 peut l'être.
  • Si l'overlay 4 est chargé, les 1, 3 et 5 ne le sont pas.
  • Si l'overlay 5 est chargé, les 2 et 3 aussi, mais les 1 et 4 ne le sont pas.
Malheureusement, quelques restrictions existent :
  • La racine peut appeler des routines de n'importe lequel des cinq overlays.
  • Les cinq overlays peuvent appeler des routines de la racine.
  • Toutes les routines de l'overlay 1 peuvent appeler d'autres routines de l'overlay 1 ainsi que toutes celles de la racine.
  • Toutes les routines de l'overlay 2 peuvent appeler d'autres routines de l'overlay 2 ainsi que celles de la racine et des overlays 3 et 4.
  • Toutes les routines de l'overlay 3 peuvent appeler d'autres routines de l'overlay 3 ainsi que celles de la racine et des overlays 2 et 5.
  • etc.
On le voit, deux noeuds de même niveau sont mutuellement exclusifs : l'overlay 1 ne peut pas appeler des routines de l'overlay 2.

Les overlays, pour qui ?

Le mécanisme des overlays n'est pas à utiliser n'importe quand. On le réserve en général pour les applications réellement énormes (plus de 100 ko).

Imaginons par exemple que vous écriviez un programme de traitement de texte. Le programme principal - la racine - contiendra toutes les routines d'entrée de caractères, d'éditions, de manipulations de bloc... Un premier overlay pourrait contenir les routines d'impression, qui n'ont pas besoin d'être chargées en permanence. Un second overlay pourrait s'occuper de l'impression en PostScript, qui est totalement différente de l'impression matricielle ou laser (on pourrait également partager le premier overlay en deux, l'un pour PostScript, l'autre pour les matricielles). Enfin, un troisième overlay pourrait gérer l'analyse du document (comptage du nombre de mots, de caractères, repérage des répétitions, histogrammes...). C'est uniquement au programmeur de décider de tout cela.

Les overlay, comment ?

C'est BLink qui se charge de presque tout, lors de la phase d'éditions de liens du programme définitif : il remplace chaque appel d'une routine appartenant à un noeud différent de celui en cours par un saut au gestionnaire d'overlays. Celui-ci décide alors, en fonction du niveau des deux noeuds concernés dans l'arborescence, s'il doit d'abord charger quelque chose depuis le disque ou non. Le gestionnaire est inclus dans les bibliothèques du Lattice, mais on peut au besoin le remplacer par un fait maison. Ce qui ne présente pas réellement beaucoup d'intérêt.

BLink utilise un fichier WITH spécial dans sa ligne de commande qui décrit l'arborscence des overlays. Le format de ce fichier est strictement défini et doit être respecté à la lettre. L'arbre de la figure 1 pourrait être décrit dans le fichier suivant :

OVERLAY
Overlay1
Overlay2
*Overlay3
**Overlay5
*Overlay4
#

Le mot-clé OVERLAY introduit le premier niveau de l'arborescence et le signe dièse (#) termine la liste. La racine n'est pas incluse : BLink utilise comme racine le premier fichier objet de sa ligne de commande (le fichier FROM ou ROOT). Une astérisque introduit un niveau supplémentaire d'overlay, pas d'astérisque du tout correspondant au niveau 1. Remarquez enfin que l'overlay 5 a été placé tout de suite derrière le 3, dont il dépend dans l'arbre.

Illustration du fonctionnement des overlays

Voici une petite illustration du fonctionnement des overlays, avec un programme parfaitement inutile, qui ne fera certainement pas date dans l'histoire de la presse informatique...

I1 faut quand même reconnaître qu'il n'est pas évident de démontrer par un court programme l'utilisation - mais aussi et surtout l'utilité - des overlays, mais j'ai tout de même décidé de le faire. Les listings qui suivent font donc partie d'un seul programme nommé "Ovls" (raccourcis pratique pour "Overlays"...). Dans l'ordre, nous avons la Racine (Racine.c), trois overlays de niveau 1 (0vl1.c, Ovl2.c et Ovl3.c) et deux overlays de niveau 2 (0vl3_1.c et Ovl3_2.c). Un fichier WITH pour BLink est également inclus, histoire de montrer comment il est conçu.

Listing 1 : Racine.c

/**********************************************************
 * Arborescence des overlays :                            *
 *                        +----------+                    *
 *                        | Racine.c |                    *
 *                        +----+-----+                    *
 *                             |                          *
 *            +--------+  +----+---+  +--------+          *
 *            | Ovl1.c +--+ Ovl2.c +--+ Ovl3.c |          *
 *            +--------+  +--------+  +---+----+          *
 *                                        |               *
 *                           +----------+ | +----------+  *
 *                           | Ovl3_1.c +-+-+ Ovl3_2.c |  *
 *                           +----------+   +----------+  *
 *********************************************************/
#include <stdio.h>

/* Fonctions de main.c */
int GetChar(void);

/* Fonctions du premier niveau de l'arbre */
extern void Ovl1(void);
extern void Ovl2(void);
extern void Ovl3(void);

/* fonction main() */
void main(int argc, char **argv)
{
int c = 0;

	if (!argc)
		return;	/* N'accepte pas le WB */

	while (c != 'q' && c != 'Q')
	{	printf("\014Démonstration du mécanisme des Overlays.\n");
		printf("\n*** Ici la Racine\n\n");

		printf("1 - Appeler l'overlay 1\n");
		printf("2 - Appeler l'overlay 2\n");
		printf("3 - Appeler l'overlay 3\n");
		printf("Q - Quitter\n");
		printf("Appeler quel overlay (1/2/3) ? ");

		switch(c = GetChar())
		{	case '1':
				Ovl1();
				break;

			case '2':
				Ovl2();
				break;

			case '3':
				Ovl3();
				break;

			default:
				break;
		}
	}
}

int GetChar(void)
{
int c1, c2;

	c1 = getchar();
	while ((c2 = getchar()) != '\n');
	return(c1);
}

Listing 2 : Ovl1.c

#include <stdio.h>

extern int GetChar(void);

void Ovl1(void)
{
	printf("\n*** Ici l'overlay 1.\n");

	printf("Une touche pour retourner à la Racine...");
	GetChar();
}

Listing 3 : Ovl2.c

#include <stdio.h>

extern int GetChar(void);

void Ovl2(void)
{
	printf("\n*** Ici l'overlay 2.\n");

	printf("Une touche pour retourner à la Racine...");
	GetChar();
}

Listing 4 : Ovl3.c

#include <stdio.h>

extern int GetChar(void);

extern void Ovl3_1(void);
extern void Ovl3_2(void);

void Ovl3(void)
{
int c = 0;

	while (c != 'r' && c != 'R')
	{	printf("\014*** Ici l'overlay 3.\n");
		printf("A - Appeler l'overlay 3_1\n");
		printf("B - Appeler l'overlay 3_2\n");
		printf("R - Retourner à la Racine\n");
		printf("Qu'est-ce qu'on fait (A/B/R) ? ");

		switch(c = GetChar())
		{	case 'a':
			case 'A':
				Ovl3_1();
				break;

			case 'b':
			case 'B':
				Ovl3_2();
				break;
		}
	}
}

Listing 5 : Ovl3_1.c

#include <stdio.h>

extern int GetChar(void);

void Ovl3_1(void)
{
	printf("\n*** Ici l'overlay 3_1.\n");

	printf("Une touche pour retourner à l'overlay 3...");
	GetChar();
}

Listing 6 : Ovl3_2.c

#include <stdio.h>

extern int GetChar(void);

void Ovl3_2(void)
{
	printf("\n*** Ici l'overlay 3_2.\n");

	printf("Une touche pour retourner à l'overlay 3...");
	GetChar();
}

Listing 7 : Makefile

Ovls:     Racine.o Ovl1.o Ovl2.o Ovl3.o Ovl3_1.o Ovl3_2.o
          Blink WITH Ovls.lnk

Racine.o: Racine.c
          Lc Racine.c

Ovl1.o:   Ovl1.c
          Lc Ovl1.c

Ovl2.o:   Ovl2.c
          Lc Ovl2.c

Ovl3.o:   Ovl3.c
          Lc Ovl3.c

Ovl3_1.o: Ovl3_1.c
          Lc Ovl3_1.c

Ovl3_2.o: Ovl3_2.c
          Lc Ovl3_2.c

Listing 8 : Ovls.lnk (fichier WITH pour BLink)

ROOT lib:c.o Racine.o
TO Ovls
LIBRARY lib:lc.lib,lib:small.lib
SMALLCODE SMALLDATA NODEBUG NOICONS

OVERLAY
Ovl1.o
Ovl2.o
Ovl3.o
*Ovl3_1.o
*Ovl3_2.o
#



[Retour en haut] / [Retour aux articles]