Transient Program Area/Base Page et comment réorganiser tout cela !
Transient Program Area (TPA):
C'est toute la mémoire qui reste disponible après chargement du système. Remarque : les programmes chargés dans la TPA sont encore appelés: "transient program"...comme par hazard.
Il y a deux vecteurs qui donnent le début et la fin de la TPA:
$4 : Adresse de début, avant cette adresse, on trouvera en fait le système.
$4 : Adresse de fin + 1. Normalement on trouve ensuite la mémoire écran.
Vous pouvez charger des programmes par la fonction Pexec ($4B) du GEMDOS. Lorsque le programme est chargé, la TPA contient le segment programme (text ou code,data, et bss), mais aussi une pile utilisateur et une base page.
La page de base:
Voir le chapitre correspondant.
La pile utilisateur:
Le système alloue une pile utilisateur d'une taille minimum de 256 octets.
Ce qui donne la configuration suivante en mémoire après chargement d'un programme :
Fin de la TPA
Pile utilisateur (minimum 256 octets) |
Espace libre réservé au programme (L'espace qui n'est pas utilisé par le code) |
BSS (suivant la taille des datas non initialisés) |
Data (suivant la taille des datas initialisés) |
Text (suivant le code) |
Base Page (256 octets) |
Début de la TPA
Bien évidemment, cette configuration n'est pas la meilleur. Car toute la TPA est réservée pour le programme. Il est donc impossible de charger un autre programme ou d'utiliser la fonction MALLOC.
Il est donc nécessaire de réorganiser tout cela afin de libérer de la mémoire.
Le but étant d'obtenir ceci:
Fin de la TPA
Espace libéré pour un autre programme ou pour une allocation mémoire par MALLOC (Espace qui n'est pas utilisé par notre code) |
Pile utilisateur (de la taille que l'on veut) |
BSS (suivant la taille des datas non initialisés) |
Data (suivant la taille des datas initialisés) |
Text (suivant le code) |
Base Page (256 octets) |
Début de la TPA
Pour arriver à cela, aurez besoin des informations contenues dans la Page de base:
Le problème étant de connaître l'adresse de la page de base. Heureusement, la fonction Pexec de GEMDOS stocke cette information dans la pile utilisateur avant de donner la main au programme.
Donc la première chose à faire dans ce programme est de récupérer cette information.
Un simple MOVE.L 4(SP), A5 suffira.
Autre chose à faire, mémoriser cette adresse tout de suite. Au cas ou nous en aurions besoin plus tard...
MOVE.L A5,PAGEBASE
Ensuite, calculer la taille réelle de du programme: Taille du texte + Taille DATA + Taille BSS récupérées de la page de base
move.l $c(a5),d0
add.l $14(a5),d0
add.l $1c(a5),d0
On y ajoute la taille de la page de base (256 octets)
add.l #256,d0
Ensuite, il ne faut pas oublier la pile:
Par exemple 4096 octets (ce qui devrait largement suffir pour un programme, mais vous pouvez mettre plus ou moins, c'est vous qui voyez).
add.l #$1000,d0
Maintenant que tout est calculé, il faut repositionnez le pointeur de pile:
move.l a5,d1 Page de Base
add.l d0,d1 Page de base + taille code + taille page base + pile
move.l d1,a7 qui donne le début de la nouvelle pile utilisateur.
Enfin, il faut libérer la mémoire inutilisée par le programme en changeant la taille de la mémoire allouée grace à la fonction MSHRINK:
Il faut pour cela: l'adresse de début de la réservation mémoire (qui correspond à la page de base) et la nouvelle taille à obtenir:
move.l d0,-(a7)
move.l a5,-(a7)
clr.w -(a7)
move.w #$4a,-(a7)
trap #1
add.l #12,a7
Et voilà, c'est terminé...