Les Fast Boot ont toujours été considérés un peu comme le Saint Graal sur la scène Underground Apple II. Et tout particulièrement chez nous, les petits frenchies. Il n'y a qu'à voir les batailles de chiffonniers que se livraient les grands acteurs de l'époque (à coup de messages rageurs, et de "Big Shit" dans leurs productions respectives) pour revendiquer la paternité de l’appellation Fast Boot, de la création du premier ou du plus rapide, j'en passe et des meilleurs... Quel groupe de l'époque (même le plus obscur) n'a pas réalisé son Copy Disk à base de Fast Boot ? C'était le passage quasi-obligé vers la renommée et la gloire (ou pas). Il faut dire que, par rapport à la lenteur d'un DOS 3.3, voir un Fast Boot se charger à la vitesse de l'éclair tenait presque de la sorcellerie pour ne pas dire du miracle...

Ce n'est un secret pour personne, j'ai toujours été émerveillé par les Fast Boot. D'ailleurs, vous avez dû vous en rendre compte car je ne perds pas une occasion (même quand il ne faut pas d'ailleurs) d'utiliser mon disque fétiche, j'ai nommé Ze Enfoirés Copy Disk. Mais les temps ont changé (ma bonne dame), et même ceux qui bidouillent encore sur Apple II, le font maintenant bien souvent par le biais d'un émulateur. Sous Windows, celui qui s'impose (hors émulation GS) est bien entendu AppleWin. Cet émulateur possède une fonction bien pratique permettant d'accélérer le transfert disque qui ne se fait plus alors en émulation temps réel mais à vitesse accélérée.

Ce mode (Enhanced Speed) est particulièrement appréciable lorsqu'on doit utiliser des softs qui sont interminables à charger (comme Merlin par exemple) ou même dans le simple cas du boot d'un bon vieux DOS 3.3. Son gros défaut, c'est qu'un certain nombre de Fast Boot sont complètement paumés lorsqu'il est activé et génèrent un beau plantage. Comme l'émulateur doit lui-même être relancé pour passer d'un mode à l'autre, cela devient vite fastidieux à la longue. Si l'on zappe fréquemment d'un Copy Disk à Merlin par exemple, tout en passant par le boot d'un disque de travail sous DOS, on s'aperçoit qu'AppleWin n'est jamais dans le mode le plus efficace et c'est la crise de nerfs assurée (ou alors je devrais peut-être prendre mes pilules)... Bref je me suis donc penché sur le problème en essayant de comprendre le pourquoi du comment et en espérant trouver une solution...

On s'aperçoit vite que les Fast Boot qui plantent sous AppleWin (en mode Enhanced Speed) sont ceux qui font le service minimum lors du BOOT 1 (donc après saut en $801 depuis la carte contrôleur) et qui sont, par là même, les plus rapides. Voici par exemple le code issu du Ze Enfoirés Copy Disk. On retrouve quasiment le même sur le Speedy Copy Disk d'Astraban ainsi que sur le FastBoot Color de Bytlejuice :

0800-   01                        ; nombre de secteur(s) à charger lors du BOOT0
 
0801-   E0 60       CPX   #$60
0803-   A9 62       LDA   #$62
0805-   20 8D 08    JSR   $088D   ; set reset vector
0808-   A9 B6       LDA   #$B6    ; Buffer Hi (Buffer primaire et final!)
080A-   85 27       STA   $27
 
080C-   BD 8C C0    LDA   $C08C,X
080F-   10 FB       BPL   $080C
0811-   49 D5       EOR   #$D5    ; check Header 1 champ DATA !
0813-   D0 F7       BNE   $080C
0815-   BD 8C C0    LDA   $C08C,X
0818-   10 FB       BPL   $0815
081A-   C9 AA       CMP   #$AA    ; check Header 2 champ DATA
081C-   D0 F3       BNE   $0811
081E-   BD 8C C0    LDA   $C08C,X
0821-   10 FB       BPL   $081E
0823-   C9 AD       CMP   #$AD    ; check Header 3 champ DATA
0825-   D0 EA       BNE   $0811
0827-   A9 00       LDA   #$00
0829-   A0 56       LDY   #$56    ; 80 nibbles
 
082B-   84 3C       STY   $3C
082D-   BC 8C C0    LDY   $C08C,X ; on commence à lire les DATA
0830-   10 FB       BPL   $082D   ;
0832-   59 D6 02    EOR   $02D6,Y ;
0835-   A4 3C       LDY   $3C
0837-   88          DEY
0838-   99 00 03    STA   $0300,Y ; vers le Buffer secondaire
083B-   D0 EE       BNE   $082B
 
083D-   84 3C       STY   $3C
083F-   BC 8C C0    LDY   $C08C,X ; lecture DATA
0842-   10 FB       BPL   $083F
0844-   59 D6 02    EOR   $02D6,Y
0847-   A4 3C       LDY   $3C
0849-   91 26       STA   ($26),Y ; vers le Buffer primaire
084B-   C8          INY
084C-   D0 EF       BNE   $083D
 
084E-   BC 8C C0    LDY   $C08C,X ;
0851-   10 FB       BPL   $084E
0853-   59 D6 02    EOR   $02D6,Y ; vérification du checksum
0856-   D0 41       BNE   $0899   ; ça colle pas ? Sortie dégueux
 
0858-   A0 00       LDY   #$00    ; début Post Nibblelisation
085A-   A2 56       LDX   #$56
085C-   CA          DEX
085D-   30 FB       BMI   $085A
085F-   B1 26       LDA   ($26),Y ; buffer primaire
0861-   5E 00 03    LSR   $0300,X ; buffer secondaire
0864-   2A          ROL
0865-   5E 00 03    LSR   $0300,X
0868-   2A          ROL
0869-   91 26       STA   ($26),Y ; sauvegarde buffer final
086B-   C8          INY
086C-   D0 EE       BNE   $085C
086E-   E6 27       INC   $27
0870-   A2 60       LDX   #$60
0872-   CE EE 08    DEC   $08EE   ; on décrémente le nb de secteurs à lire
0875-   D0 95       BNE   $080C
 
0877-   20 58 FC    JSR   $FC58   ; efface écran
087A-   A0 27       LDY   #$27
087C-   B9 A4 08    LDA   $08A4,Y ; routine affichage message boot
087F-   49 A0       EOR   #$A0    ; petite décodage
0881-   99 00 04    STA   $0400,Y ; envoie vers première ligne écran
0884-   88          DEY
0885-   10 F5       BPL   $087C
0887-   4C 00 B6    JMP   $B600   ; saut Boot 2. Voilà c'est fini !
088A-   4C A9 FA    JMP   $FAA9
 
088D-   8D F4 03    STA   $03F4   ; fixe le reset vector
0890-   AD 51 C0    LDA   $C051   ; page 1
0893-   A9 00       LDA   #$00    ;
0895-   8D F2 03    STA   $03F2   ; CTRL+POMME+RESET = $C600G
0898-   A9 C6       LDA   #$C6    ;
089A-   8D F3 03    STA   $03F3   ;
089D-   60          RTS   
 
089E-   F9 F9 F9    SBC   $F9F9,Y
08A1-   F9 F9 F9    SBC   $F9F9,Y
 
; Message Boot (EOR $A0)
08A4-   E3          ???
08A5-   AF          ???
08A6-   B0 B9       BCS   $0861
08A8-   80          ???
08A9-   E6 A2       INC   $A2
08AB-   AF          ???
08AC-   AF          ???
08AD-   B4 80       LDY   $80,X
08AF-   E2          ???
08B0-   B9 80 EB    LDA   $EB80,Y
08B3-   B2          ???
08B4-   A9 B3       LDA   #$B3
08B6-   B4 AF       LDY   $AF,X
08B8-   80          ???
08B9-   E6 B2       INC   $B2
08BB-   AF          ???
08BC-   AD 80 FA    LDA   $FA80
08BF-   A5 80       LDA   $80
08C1-   E5 AE       SBC   $AE
08C3-   A6 AF       LDX   $AF
08C5-   A9 B2       LDA   #$B2
08C7-   A5 B3       LDA   $B3
08C9-   80          ???
08CA-   C1 C1       CMP   ($C1,X)
 
08CC-   ED F0 F2    SBC   $F2F0
08CF-   DF          ???
08D0-   EC F3 F0    CPX   $F0F3
08D3-   EB          ???
08D4-   DF          ???
08D5-   E9 F6       SBC   #$F6
08D7-   DF          ???
08D8-   D3          ???
08D9-   DF          ???
08DA-   F9 FD F0    SBC   $F0FD,Y
08DD-   F0 EB       BEQ   $08CA
08DF-   DF          ???
08E0-   FD E6 DF    SBC   $DFE6,X
08E3-   EB          ???
08E4-   ED F0 F3    SBC   $F3F0
08E7-   F3          ???
08E8-   DF          ???
08E9-   D9 DF FC    CMP   $FCDF,Y
08EC-   F0 D1       BEQ   $08BF
 
08EE-   06          ???            ; nb secteurs à charger
 
08EF-   FE          ???
08F0-   A5 25       LDA   $25
08F2-   C9 18       CMP   #$18
08F4-   D0 ED       BNE   $08E3
08F6-   A9 04       LDA   #$04
08F8-   85 25       STA   $25
08FA-   A9 00       LDA   #$00
08FC-   85 FE       STA   $FE
08FE-   A0 1C       LDY   #$1C

Ce qui frappe immédiatement quand on examine d'un peu plus près cette routine, c'est qu'elle ne lit jamais le champ adresse, elle ne vérifie donc pas sur quel secteur elle est, et donc ce qu'elle charge...
Et c'est là toute la clé du mystère et ce qui fait que ce type de Fast Boot ne passe pas sous AppleWin (en mode Enhanced Speed). Récapitulons ce qui se passe :

  • le secteur 0 a donc été chargé en $800, lors du Boot 0 par la ROM de la carte contrôleur (ceci est immuable).
  • la routine en $801 est exécutée (par le JMP $801 présent en ROM en $C6F8 si carte en SLOT 6).
  • pendant ce temps le disque continue de tourner (car il ne s'arrête jamais tant que le drive est allumé) et la tête se retrouve au-dessus d'un certain secteur (elle n'est évidemment pas restée scotchée sur le secteur 0).
  • la routine va alors charger ce secteur et le décoder...
  • le disque tourne toujours, la tête de lecture est maintenant au dessus d'un autre secteur...
  • la routine lit ce nouveau secteur, le décode et...
  • répète la même chose pour tous les autres secteurs encore à lire (avec à chaque fois, le disque qui, continuant à tourner, positionnera un nouveau secteur sous la tête de lecture ).

Évidemment, les secteurs lus ne le sont pas au petit bonheur la chance... Le Fast Boot a été conçu de telle manière qu'à chaque fois qu'il y a lecture d'un secteur, la tête est au dessus d'un emplacement bien précis. La routine n'a alors plus qu'à localiser le champ DATA et y lire les données.

Déterminons donc quels sont les secteurs qui sont lus et vers où. Pour ce faire, nous allons utiliser la méthode empirique ! Il suffit de boot tracer jusqu'à la fin du Boot 1 et de voir ce qui a alors été chargé aux adresses $B600,$B700,etc. et de vérifier à quel secteur cela correspond sur le disque avec Disk Fixer par exemple (ça tombe bien il est présent sur Ze Enfoirés Copy Disk !).
Il suffira ensuite de faire la même chose avec le mode Enhanced Speed enclenché et de comparer le tout.

Voici un tableau récapitulatif des résultats pour Ze Enfoirés Copy Disk (ainsi que pour Speedy Disk Copy à titre de comparaison) :

(Interleaving DOS 3.3)ZE ENFOIRÉS COPY DISKSPEEDY DISK COPY
Adresse de chargementSecteur logique
Mode Authentic
Secteur logique
Mode Enhanced
Secteur logique
Mode Authentic
Secteur logique
Mode Enhanced
$B600$0E$07$0E$07
$B700$0D$0E$0D$0E
$B800$0C$06$0C$06
$B900$0B$0D$0B$0D
$BA00$0A$05$0A$05
$BB00$09$0C$09$0C
$BC00-$08$04

Le résultat est sans appel. En mode Enhanced Speed, ce ne sont pas les mêmes secteurs qui sont chargés. Donc forcément, quand à la fin du Boot 1, le JMP $B600 arrive, on se retrouve à sauter (à pieds joints) dans le vide intersidéral !
En mode Enhanced Speed, l'émulateur semble charger "bêtement" les secteurs physiques 1 à 6, ce qui ne correspond bien évidemment pas à ceux chargés originellement par le Fast Boot, qui utilise un interleaving particulier.

Note : pour en savoir plus sur l'interleaving (principe, fonctionnement etc), vous pouvez consultez l'article de JPL ainsi que celui de Deckard.

Si on part du principe que le Fast Boot charge les secteurs 1 à 6 avec son propre interleaving, on peut donc déduire celui-ci par équivalence, ce qui donne le tableau ci-dessous :

Secteur logique
(Fast Boot)
Secteur physique n°Secteur logique
(DOS 3.3)
$00$00$00
-$01$07
$01$02$0E
-$03$06
$02$04$0D
-$05$05
$03$06$0C
-$07$04
$04$08$0B
-$09$03
$05$0A$0A
-$0B$02
$06$0C$09
-$0D$01
$07$0E$08
-$0F$0F

Pour vérifier la validité de ce tableau, j'ai effectué un petit test en modifiant le Boot 1 de Ze Enfoirés Copy Disk afin de lui faire charger $0F secteurs à partir de l'adresse $2100. Et j'ai bien entendu marqué les secteurs afin de les repérer en mémoire. Une petite modification du JMP $B600 en JMP $FF59 et nous voilà avec un joli disque de test. Résultats : seuls les secteurs de 1 à 7 sont réellement chargés. Ensuite, on retrouve en mémoire les secteurs 0 à 8 qui auront été chargés une seconde fois. Il semble bien que l'interleaving utilisé par le Fast Boot soit limitatif. Voyons cela plus clairement :

Ci-contre un petit schéma (dont la base provient du livre de Jean-Pierre Lagrange "Système d'Exploitation et Système de Protection sur Apple II") modifié par mes soins (classe hein ? ! oui hmm hmm) afin d'y ajouter l'interleaving de notre Fast Boot. On comprend mieux pourquoi, une fois le tour complet du disque effectué (donc après lecture du 7ème secteur), l'interleaving du Fast Boot fait que l'on retombe sur le secteur 0, puis 1 etc... D'où rechargement des mêmes secteurs en mémoire.
On voit également que le disque n'a le temps de se déplacer (en tournant) que de deux secteurs avant que la routine effectue une nouvelle lecture. Sous Prodos (et Pascal), on a un décalage de 4 secteurs. Sous Dos 3.3, on en parle même pas tellement le décalage (et la lenteur qui en résulte) est important...

 

Une fois compris pourquoi le Fast Boot plante en mode Enhanced Speed, ma première idée fut donc de replacer au bon endroit les secteurs de façon à ce qu'ils correspondent à ce qui est réellement chargé : ce qui est écrit en $B600 provient sur le disque non retouché du secteur logique $0E, on l'a vu plus haut (voir tableau). Or, en mode Enhanced, le secteur qui est chargé en $B600 est le $07. Il suffit donc de mettre le contenu du secteur $0E dans le secteur $07 ! C'est d'autant plus simple que sur Ze Enfoirés Copy Disk, les secteurs $01 à $08 ne servent absolument à rien. On déplace donc ainsi de la même manière les 6 secteurs ($0E->$07, $0D->$0E, $0C->$$06,$0B->$0D,$0A->$05 et $09->$0C). Et le résultat est parfaitement fonctionnel ! Seul "petit" souci, le disque ainsi modifié ne peut booter correctement que sous AppleWin et en mode Enhanced Speed forcément. Hors de question de l'utiliser sur un autre émulateur. Et bien entendu, mettre une telle image sur disquette physique conduirait droit dans le mur lors du boot sur un vrai Apple II. Mais l'essentiel est là : nous avons rendu notre Fast Boot fonctionnel en mode Enhanced Speed !

Mais l'histoire ne s'arrête pas là car je suis tombé sur le Speedy Boot de MICMAC and THE SOFTMAN, un Fast Boot fonctionnel lui, peu importe le mode sous AppleWin. Il utilise une technique de chargement totalement différente. En fait, les x secteurs nécessaires au boot et à la RWTS du Fast Boot en lui-même sont tous chargés lors du Boot 0 par la carte contrôleur. Il suffit pour cela de mettre le nombre de secteurs à charger sur le premier octet du premier secteur de la première piste. C'est le fameux nombre que l'on retrouve en $800 après le Boot 0 ! La phase Boot 1 (qui commence en $801) ne sert en fait qu'à déplacer ce qui a été chargé vers les bonnes adresses. Car oui, le Boot 0 chargera systématiquement les secteurs à la suite à partir de l'adresse $800, adresse rarement pratique dans le cas d'une RWTS vous en conviendrez...

J'ai donc eu l'idée (folle) d'utiliser la même technique pour charger, dès le Boot 0, les 6 secteurs nécessaires au fonctionnement de Ze Enfoirés Copy Disk. Et ensuite, quand la carte contrôleur saute en $801, il suffit d'effectuer le déplacement de ce qui aura été chargé en $900+ vers les bonnes adresses (soit $B600+).
Mais comment disposer physiquement les données sur le disque ? Et bien le Boot 0 va charger dans l'ordre les secteurs physiques (en se référant aux headers du champ adresse), il faut donc mettre les données dans les secteurs logiques correspondants avec DiskFixer (qui travaille en utilisant la RWTS DOS donc avec l'interleaving DOS 3.3). Le secteur physique 1 (chargé en $900) devra donc être le secteur logique $07, le second (chargé en $A00) devra donc être le secteur logique $0E et ainsi de suite (voir le tableau ci-dessous) :

Boot MICMAC/THE SOFTMAN adapté pour Ze Enfoiré Copy Disk (et Speedy Disk Copy)
Secteur physique numéro :Secteur logique numéro :chargé en mémoire en :à déplacer vers :
$00$00$800-
$01$07$900$B600
$02$0E$A00$B700
$03$06$B00$B800
$04$0D$C00$B900
$05$05$D00$BA00
$06$0C$E00$BB00
$07 (*)$04$F00$BC00

(*) : le secteur physique 7 à déplacer vers $BC00 ne concerne que Speedy Copy Disk.

Et voici le code à mettre Secteur 0/Piste 0 :

0800- 07                           ; $07 secteurs à charger !
                                   ; $01 (pour le secteur 0 comme d'habitude)
                                   ; + les $06 secteurs de la RWTS du Fast Boot !
0801-   20 80 08    JSR   $0880    ; sous-routine "initilisations" si besoin
0804-   A0 27       LDY   #$27     ; décodage message boot
0806-   B9 A4 08    LDA   $08A4,Y  ; repris tel quel de Ze Enfoiré Copy Disk
0809-   49 A0       EOR   #$A0     ;
080B-   99 00 04    STA   $0400,Y  ;
080E-   88          DEY
080F-   10 F5       BPL   $0806
0811-   A0 00       LDY   #$00     ; début déplacement
0813-   B9 00 09    LDA   $0900,Y  ; $900->$B600 (SP 1 / SL $07)
0816-   99 00 B6    STA   $B600,Y
0819-   B9 00 0A    LDA   $0A00,Y  ; $A00->$B700 (SP 2 / SL $0E)
081C-   99 00 B7    STA   $B700,Y
081F-   B9 00 0B    LDA   $0B00,Y  ; $B00->$B800 (SP 3 / SL $06)
0822-   99 00 B8    STA   $B800,Y
0825-   B9 00 0C    LDA   $0C00,Y  ; $C00->$B900 (SP 4 / SL $0D)
0828-   99 00 B9    STA   $B900,Y
082B-   B9 00 0D    LDA   $0D00,Y  ; $D00->$BA00 (SP 5 / SL $05)
082E-   99 00 BA    STA   $BA00,Y
0831-   B9 00 0E    LDA   $0E00,Y  ; $E00->$BB00 (SP 6 / SL $0C)
0834-   99 00 BB    STA   $BB00,Y
0837-   C8          INY
0838-   D0 D9       BNE   $0813
083A-   4C 00 B6    JMP   $B600    ; GO BOOT 2
083D-   00          BRK
083E-   00          BRK
...     00          BRK
...     00          BRK
087E-   00          BRK
087F-   00          BRK
0880-   20 58 FC    JSR   $FC58        ; effacement écran
0883-   60          RTS                ; il y a de la place
0884-   00          BRK                ; pour mettre ce que l'on veut...
0885-   00          BRK
...     00          BRK
...     00          BRK
08A2-   00          BRK
08A3-   00          BRK
08A4-   E3          ???                ; début texte message boot codé
08A5-   AF          ???
08A6-   B0 B9       BCS   $0861
08A8-   80          ???
08A9-   E6 A2       INC   $A2
08AB-   AF          ???
08AC-   AF          ???
08AD-   B4 80       LDY   $80,X
08AF-   E2          ???
08B0-   B9 80 EB    LDA   $EB80,Y
08B3-   B2          ???
08B4-   A9 B3       LDA   #$B3
08B6-   B4 AF       LDY   $AF,X
08B8-   80          ???
08B9-   E6 B2       INC   $B2
08BB-   AF          ???
08BC-   AD 80 FA    LDA   $FA80
08BF-   A5 80       LDA   $80
08C1-   E5 AE       SBC   $AE
08C3-   A6 AF       LDX   $AF
08C5-   A9 B2       LDA   #$B2
08C7-   A5 B3       LDA   $B3
08C9-   80          ???
08CA-   C1 C1       CMP   ($C1,X)
08CC-   00          BRK
08CD-   00          BRK
...     00          BRK
...     00          BRK
08FE-   00          BRK
08FF-   00          BRK

Comme vous pouvez le voir, c'est viiiiiiiiiide ! Il n'y a rien à part la routine de déplacement. J'ai repris le décodage et le texte du message de boot histoire de conserver un look similaire à l'original.
Les plus attentifs noteront toutefois une différence en ce qui concerne l'affichage de ce message. Dans le Fast Boot original, il s'affiche AVANT le chargement des 6 secteurs contenant la RWTS et le code du FastBoot. Après modification, le message ne s'affiche qu'après (puisque les 6 secteurs sont chargés dans la foulée du secteur 0).
À noter également que le code pour Speedy Copy Disk sera légèrement différent, un secteur supplémentaire est à charger lors du Boot 0, il y aura donc un déplacement de plus à effectuer ainsi qu'une ou deux initialisations indispensables pour la suite.

Nous obtenons donc un Ze Enfoirés Copy Disk, capable de booter sous AppleWin en Enhanced speed, capable de booter correctement sous les autres émulateurs (normalement) mais également capable de booter sur un vrai Apple II ! Vu que l'on retrouve ce type de Fast Boot sur énormément de productions de l'époque (surtout parmi celles de Godfather and co), cela représente un certain nombre de disques concernés. Et on peut adapter la bidouille pour le Speedy Disk Copy et les autres Fast Boot utilisant le même type de Boot 1.

Évidemment cela représente une relativement grosse modification (on est loin du petit patch de quelques octets). Voilà qui pourrait servir de base à la réalisation de notre propre Copy Disk. Un jour peut-être...

En attendant, je me suis amusé à faire quelques tests de rapidité. Rien de sophistiqué à l'époque des benchmarks de folie, ici tout se fait à l'ancienne : un chrono, un doigt et un œil. Je lance le chrono à l'allumage de l'Apple II et le stoppe dès que je vois apparaître l'écran de sélection. La précision est évidemment un peu merdique mais c'est juste pour avoir une idée :
- sur un vrai Apple IIe, le résultat est sans appel : le Fast Boot original de Ze Enfoirés Copy Disk est plus rapide d'une seconde (environ 3s pour avoir l'écran de sélection contre 4s avec notre disque modifié) ! La seule consolation c'est évidemment que le disque modifié fonctionne parfaitement à partir d'une vraie disquette (mais cela reste anecdotique et sans véritable intérêt, autant utiliser l'original).
- sous AppleWin, je lance le chrono en appuyant sur la Pomme (simulant un reboot machine). En mode Authentic Speed tout d'abord :  Le Fast Boot original se lance en 2.7s, notre disque modifié en 3.1s. Passons en mode Enhanced Speed maintenant, la véritable raison d'être de notre Enhanced Fast Boot (tada !), évidemment le Fast Boot original ne boot pas (sinon j'aurais passé un après-midi à écrire cet article pour rien...). Quant à notre disque modifié, l'écran de sélection s'affiche au bout de 0.6s ! Vavavoommm mes amis !

Je vous invite chaleureusement à télécharger Ze Enfoirés Copy Disk - Enhanced Version et à le tester par vous-même sous AppleWin !

Ah et contrairement à ce que l'image d'intro laisse supposer, je n'ai fait aucune modification cosmétique à l'original. Je suis bien trop respectueux pour ça !