Nous avons vu lors de l'analyse de l'Autostart qu'à allumage d'un Apple II, était récupéré le contenu des adresses $FFFC et $FFFD pour trouver en quelque sorte le point d'entrée de la ROM et y sauter. En fait, quand on appuie sur CTRL+RESET (ou RESET tout court sur les premiers Apple II), il se passe exactement la même chose : la patte 40 du 6502 est mise à la masse, il y a alors saut inconditionnel à l'adresse contenue en $FFFC/$FFFD. C'est seulement à cette adresse ($FA62 sur une ROM Autostart) qu'une routine détermine grosso modo si on vient d'allumer l'ordinateur (et dans ce cas, saute à la partie COLDSTART avec détection des slots) ou si on fait juste un "RESET" ordinateur allumé (et saute alors au WARMSTART).
FA62- D8 CLD FA63- 20 84 FE JSR $FE84 FA66- 20 2F FB JSR $FB2F FA69- 20 93 FE JSR $FE93 FA6C- 20 89 FE JSR $FE89 FA6F- AD 58 C0 LDA $C058 FA72- AD 5A C0 LDA $C05A FA75- A0 09 LDY #$09 FA77- 20 B4 FB JSR $FBB4 FA7A- EA NOP FA7B- AD FF CF LDA $CFFF FA7E- 2C 10 C0 BIT $C010 FA81- D8 CLD FA82- 20 3A FF JSR $FF3A FA85- AD F3 03 LDA $03F3 ; vecteur reset (hi) FA88- 49 A5 EOR #$A5 ; vérification avec FA8A- CD F4 03 CMP $03F4 ; l'octet de contrôle FA8D- D0 17 BNE $FAA6 ; non égal ? Alors COLDSTART ! ; sinon WARMSTART: FA8F- AD F2 03 LDA $03F2 ; vecteur reset (lo) non nul ? FA92- D0 0F BNE $FAA3 ; si oui, on y va... FA94- A9 E0 LDA #$E0 ; vecteur reset (hi) FA96- CD F3 03 CMP $03F3 ; = $E0 ? FA99- D0 08 BNE $FAA3 ; non ? alors on y va... FA9B- A0 03 LDY #$03 ; si oui (donc = $E000 = Basic Cold Entry) FA9D- 8C F2 03 STY $03F2 ; modification reset vector en Warm entry FAA0- 4C 00 E0 JMP $E000 ; puis saut au BASIC (Cold Entry) FAA3- 6C F2 03 JMP ($03F2) ; saut vecteur reset (dans les autres cas) |
C'est surtout la seconde moitié qui nous intéresse (la première partie étant consacrée à des initialisations diverses notamment en page 0 ainsi que le positionnement de l'affichage en page text 1).
On voit que la seule vérification décidant s'il s'agit d'un COLDSTART ou d'un WAMRSTART a lieu au niveau de l'octet $3F4. Celui-ci, de son petit nom officiel PWREDUP, est une sorte d'octet de contrôle du vecteur Reset. Son contenu doit être égal à celui de $3F3 EOR #$A5. Si ce n'est pas le cas (peu importe sa valeur), la ROM décide qu'elle doit faire un COLDSTART et saute donc à la routine en $FAA6.
À l'allumage de l'ordinateur, $3F4 contient $FF ($3F2 et $3F3 contenant $00). La condition ($3F4 = $3F3 EOR #$A5) n'est donc pas vérifiée, d'où le COLDSTART effectué (logique, on vient d'allumer la machine...).
Le vecteur reset ($3F2/$3F3) et son octet de contrôle ($3F4) peuvent être définis par l'utilisateur. Lorsque l'on appuie sur CTRL+Reset (ou Reset sur II+), deux cas peuvent se présenter :
- si le vecteur Reset est correctement défini (c'est à dire si son octet de contrôle est OK), on saute vers l'adresse issue du vecteur Reset (peu importe sa valeur d'ailleurs, seul l'octet de contrôle décide de tout).
- si l'octet de contrôle ne vérifie pas l'égalité $3F3 EOR #$A5, le COLDSTART est appelé à la rescousse.
Les éditeurs (et autres petits malins) utiliseront ces possibilités (vecteur Reset qui pointe vers $C600 par exemple ou octet de contrôle corrompu) pour forcer un reboot et éviter ainsi que l'on puisse récupérer la main en cas de Reset.
Le but de la modification du jour est donc de faire en sorte de sauter vers le Monitor ($FF59) en toute circonstance, que le vecteur Reset soit correctement défini ou pas.
On pourrait à l'image des premiers Apple II (OLD ROM) modifier les adresses $FFFC/$FFFD pour y mettre directement $59 et $FF. Cela marcherait très bien et ne serait pas contournable. Mais on se priverait ainsi de l'Autostart qui est bien agréable au quotidien pour booter directement sur le premier lecteur rencontré. Et cela shunterait aussi la modification vue précédemment pour ce même Autostart.
Il faut donc faire en sorte de ne sauter vers le COLDSTART qu'à l'allumage de l'ordinateur mais plus après. Peu importe les modifications effectuées sur le vecteur Reset et/ou l'octet de contrôle par les programmes chargés en mémoire.
Pour ce faire, la modification proposée va tester le contenu de $3F2, $3F3 et $3F4. Si on a $00 pour les deux premiers et $FF pour le troisième, il y a de très grandes chances que l'on soit en phase d'allumage et non pas de Reset. On laisse donc le COLDSTART s'exécuter. Si une seule des trois adresses ne contient pas ce qui est attendu, nous ne sommes forcément plus en phase d'allumage et on saute donc au Monitor :
FA85- AD F2 03 LDA $03F2 ; test vecteur reset FA88- D0 0C BNE $FA96 ; non nul ? FA8A- AD F3 03 LDA $03F3 ; idem FA8D- D0 07 BNE $FA96 ; FA8F- AD F4 03 LDA $03F4 ; test octet contrôle FA92- C9 FF CMP #$FF ; égal à #$FF ? FA94- F0 10 BEQ $FAA6 ; oui ? alors go COLDSTART ! FA96- 4C A3 FA JMP $FAA3 ; saut intermédiaire (voir note) FA99- 00 00 ; octets inutilisés (mis à 00) FA9B- A0 03 LDY #$03 ; routine originale FA9D- 8C F2 03 STY $03F2 ; que l'on conserve car FAA0- 4C 00 E0 JMP $E000 ; utilisée par la modif Autostart FAA3- 4C 59 FF JMP $FF59 ; saut monitor ! |
La routine est on ne peut plus simple : test du vecteur reset, si quelque chose a été modifié, on saute au Monitor, sinon on fait un COLDSTART. Cette routine prend la place de celle décrite plus haut. Et elle est compatible avec les IIe Enhanced et UnEnhanced (et logiquement II+).
Elle est bien sûr compatible avec la modification Autostart qui en cas d'appui sur 0 saute en $FA9B (d'où les résidus du code original en $FA9B utilisés par notre modification Autostart).
Le saut intermédiaire en $FA96, a priori superflus, a en fait deux utilités : préparer le code pour la version évoluée de la modification, tout en permettant l'ajout d'une option supplémentaire au patch Autostart (saut au Monitor au lieu du Basic par appui sur 0 - voir la mise à jour de la page concernée).
Bien sûr, si par malchance, un programme s'amuse à mettre $00 en $3F2 et $3F3 et $FF en $3F4, alors notre ROM modifiée se fera berner en beauté et lors d'un RESET, exécutera l'Autostart, se croyant à l'allumage ! C'est le point faible de la modification. Et aussi le prix à payer pour avoir une routine la moins contraignante possible en temps normal. Certaines modifications de ROM proposaient par exemple d'appuyer sur une troisième touche (en plus de CTRL et RESET) pour obtenir le Monitor. J'ai choisi une autre voie, en misant sur la faible probabilité de trouver la séquence 00 00 FF volontairement redéfinie par un programme pour le vecteur Reset.
Pour effectuer concrètement la modification, prenez votre image ROM (déjà modifiée ou non) et remplacez les octets correspondants avec un éditeur Hexa à partir de l'offset :
- image ROM (IIe Enhanced, UnEnhanced ) : $1A85
- fichier F8.rom (AppleWin) : $285
Vérifiez toujours avant de faire vos modifications que les octets originaux soient bien à l'endroit attendu. On trouve plusieurs ROM Apple II sur le Net, dans différentes versions et sous différentes formes. Méfiance donc...