6Fermer8
deleted2Le 03/05/2009 à 21:55
Bon.
Alors la calculatrice s'éteint de la manière suivante : le romcall off() appelle le trap #4 (c'est un vecteur, ie une routine qui est exécutée, et dont l'adresse se situe à $8C). La routine est donc exécutée, et éteint l'écran, divers oscillateurs etc... Quand elle se rallume, le trap #4 se termine et rend la main là où on l'avait appelé. Comme l'a dit squalyl, c'est par là qu'il faut attaquer pour faire ce que tu veux :
tu vas remplacer l'adresse de ce qu'exécute AMS à $8C (mettons $00123456) par la tienne, au pif $00654321, si ton code se situe là. Comme ça, c'est ton code qui va être exécuté, non celui d'AMS. Ca s'appelle une redirection. Le but du jeu est de faire :
-> la calculatrice lance le code contenu à l'adresse de $8C, donc elle exécute le code à $00654321.
-> on a donc la main avec notre routine. on exécute le code à $00123456, adresse qu'on a pris soin de retenir avant de la remplacer par la notre : la calculatrice s'éteint., puis nous rend la main : on a donc la main dès le démarrage.
-> on exécute ensuite le code qu'on veut (genre printf("Windows est en cours de démarrage"), ou mieux, printf("Uncompressing the kernel..."), 'fin bref, t'as le choix tripo).

Ca, c'est pour le principe. Maintenant, comemnt faire concrètement ?
Ton code va être en deux parties :
- le code d'installation et de désinstallation, qui va s'exécuter quand on va lancer ton programme. Il ne sert qu'une fois, et mets en place le TSR, ou le désinstalle s'il est déjà en place.
- le code de l'interruption proprement dit, qui s'exécutera à chaque exctinction et à chaque démarrage.

Rentrons dans les détails croustillants :

installation/désinstallation :
- tu lis l'adresse située à $8C, tu sais donc où se trouve en mémoire le handler (le code d'interuption) du trap #4.
- tu lis l'adresse de l'interuption que tu veux installer, c'est à dire ton propre code dans ton programme d'installation
- tu compares octet par octet le code de ces deux interuptions
a. si les binaires sont différents, ça veux dire que ton interuption n'est pas installée. On est donc dans un cas d'installation
b. si le binaire du handler est le même que ton code (sauf un détail, voir suite), ça veut dire que c'est déjà ton TSR qui est installé, donc on est dans un cas de désinstallation.

a. Installation
- On pourrait être tenté de mettre à l'adresse $8C l'adresse du code qu'on a préparé dans le programme : lea Interruption(pc),a0 / move.l a0,$8C. Erreur : ton programme, une fois achévé, a toute les chances de bouger en RAM. Et pourtant, le trap #4 appellera toujours du code situé là où ton programme était lors de l'installation : crash garanti.
Il faut donc recopier le code de ton interruption quelque part en mémoire, pour ne plus qu'il y bouge. Regarde les fonctions HeapAllocPtr et HeapAllocHigh. Evite d'utiliser HeapAlloc, tu vas allouer en mémoire basse, puis locker (HeapLock), ça va fragmenter ta RAM.
Alloue donc de la mémoire, puis lock le handle si nécessaire (ie si la fonction d'allocation ne le fait pas elle-même). Pour ce qui est de la taille du handle à allouer, tu peux la connaitre par une simple différence de labels : (FinInteruption - DebutInteruption).

b. Désinstallation
- tu retrouves le numéro de ton handle, ou tu cnoserves son adresse (tu auras besoin de l'un ou de l'autre suivant comment tu l'auras créé, regarde HeapPtrToHandle si t'as besoin du handle).
- tu remplaces le contenu de $8C par ce que t'avais enregistré à la place de ton 0.l
- tu désalloue ton handle
- ayé, fini. smile

c. Le tsr proprement dit
Voyons le contenu à proprement parler de ton TSR maintenant.
Le moyen le plus simple que j'avais trouvé pour exécuter l'ancien trap 4, c'est, une fois que ton tsr est lancé, de réinstaller l'ancien trap 4, de l'appeler, puis de réinstaller le tien en écrivant juste l'adresse du début du handler dans la table des vecteurs. Un autre moyen doit être d'appeler l'ancien handler avec un jsr, en ayant pris soin de pousser le SR sur la pile, vu que le code du trap se termine par rte et non par rts. Je sais pas pourquoi j'avais opté pour la première option, peut-être par manque de connaissances, je sais plus.
Après, la calc est redémarrée, le processeur t'appartient, à toi de lui faire faire ce que tu veux. smile

d. Note sur l'installation d'un vecteur
Pour d'évidentes raisons de protection du système, on ne peut pas écrire dans la table des vecteurs sans déclencher une erreur, sans avoir désactiver la protection en écriture dans cette table.
Pour désactiver la protection, il faut mettre à 0 le bit #2 à $600001. Bien évidemment, faut le remettre à 1 une fois que t'as fait ton écriture. Le top est, en trois instruction, de mettre le bit $600001:2 à 0, d'écrire ce que tu veux, puis de remettre le bit à 1. Sinon au moindre bug, tu fous la table en l'air ^^