Et un nouveau défi musical, un ! Il se trouve, cette fois, sur le disque anniversaire diffusé début 1987 par QTIPS pour fêter sa première année de participation active sur la scène Apple II. On y retrouve donc un petit aperçu de ses multiples contributions, démontrant s'il était besoin, que QTIPS a été un acteur majeur de l'underground FR de cette époque. Quant au défi en lui-même, toujours le même principe : extraire la musique et en faire un fichier exécutable le plus petit possible et autonome. Un grand merci, au passage, à Antoine qui m'a permis de récupérer l'image disque de cette production. Il aurait été dommage de passer à côté...

Pour commencer un défi, je ne le répéterai jamais assez : il faut observer ! La chose la plus flagrante ici, c'est que l'on retrouve un lecteur de fichier texte (donc après l'intro musicale) qui ressemble grandement à celui de Miami Sound Machine Maker. Et on se souvient que celui-ci était écrit en BASIC. On peut donc essayer d'office de faire un petit CTRL+C lors du boot pour voir ce que cela donne (après l’apparition du texte HAPPY BIRTHDAY QTIPS par exemple). Et presque sans surprise, on voit que cela fonctionne car un beau BREAK surgit à l'écran.

Juste une illusion...

Voici ce qu'on obtient si on fait un LIST 1-10. Il y a bien une ligne 0 mais qui apparemment génère uniquement un tas de sauts de ligne, histoire de bien nous pourrir la vie. Bref on la zappe...
Cette fois, pas de BLOAD PLAYER ou autre... On voit que le lecteur texte, qui commence dès la ligne 4 devrait donc être logiquement précédé de la musique. Si on fait un RUN, on a effectivement affichage de la page graphique et la musique...  OK, donc en 3 lignes dont une de REM, on doit avoir tout ça... On sent déjà qu'il y a quelque chose qui ne colle pas... On remarque aussi les " :" au début des lignes 2, 3 et 4. Bref il y a un truc de pas net dans ce listing. Une seule solution, passer sous Monitor et regarder ce qu'il y a vraiment en mémoire. Pour info, je rappelle qu'un programme BASIC est (normalement) en mémoire à partir de $801 (on peut le vérifier par le contenu des adresses en page zéro $67 et $68).
Voici décortiqué pour vous ce qui se passe réellement quand on lance le programme par RUN pour chacune des 4 premières lignes. Ouvrez bien les yeux car l'essentiel du défi est là.

Ligne 0 :

0801-   F1 08         ; adresse ligne suivante (=$8F1)
0803-   00 00         ; numéro basic de la ligne = 00
0805-   B2            ; TOKEN commande REM
0806-   0A            ; CTRL+J
0807-   0A            ; soit déplacement du curseur
0808-   0A            ; vers le bas d'où le
0809-   0A            ; scrolling vers le haut de
080A-   0A            ; l'écran qui se remplit
080B-   0A            ; de vide
080C-   0A            ;
080D-   0A            ; oui on va couper
080E-   0A            ; parce qu'il y en a
080F-   0A            ; pour long...
...
...
08ED-   0A
08EE-   0A
08EF-   0A
08F0-   00            ; fin de la ligne 0 !

La Ligne 0 ne fait rien d'autre que de nous pourrir un peu l'écran en utilisant un CTRL+J (déplacement du curseur vers le bas) répété maintes et maintes fois... Next !

Ligne 01 :

08F1-   0D 09         ; adresse ligne suivante (=$90D)
08F2-   01 00         ; numéro basic de la ligne = 01
08F5-   B9            ; TOKEN commande POKE
08F6-   32 31 34      ; "214"
08F9-   2C            ; ","
08FA-   31 32 38      ; "128"
08FD-   3A            ; ":"
08FE-   B9            ; TOKEN commande POKE
08FF-   31 30 31 32   ; "1012"
0903-   2C            ; ","
0904-   30            ; "0"
0905-   3A            ; ":"
0906-   A5            ; TOKEN commande ONERR
0907-   AB            ; TOKEN commande GOTO
0908-   36 30 30 30   ; "6000"
090C-   00            ; fin de la ligne 1

Ici aucune surprise ni fourberie, la ligne fait exactement ce qui apparaît dans le listing. Pour info, le POKE 214,128 transforme toute commande direct (comme LIST) en RUN ! C'est à dire qu'une fois exécuté, vous ne pourrez plus lister le programme BASIC par exemple car il y aura re-run automatique (et plantage ici). Quant au POKE 1012,0 c'est le RESET VECTOR. En le forçant à zéro, il y aura reboot systématique en cas de CTRL-POMME-RESET. Bref des mesures de rétorsion pour les plus bourrins ! La ligne 6000, elle, contient un simple RESUME.
Pour ceux qui découvrent l'envers du décor d'un programme BASIC, on voit que c'est un mélange de commandes sous forme de TOKEN (codé sur un octet) et d'ASCII pour les paramètres de la commande. Allez on continue !

Ligne 02 :

090D-   62 09         ; adresse ligne suivante (=$962)
090F-   02 00         ; numéro basic de la ligne = 02
0911-   B0            ; TOKEN commande GOSUB
0912-   37 30 30 30   ; "7000"
0916-   3A            ; ":"
0917-   B2            ; TOKEN commande REM
0918-   20            ; ESPACE
0919-   08            ; CTRL+H (déplacement gauche)
...                   ; et ça continue
...                   ; encore et
092A-   08            ; encore
092B-   3A            ; ":"
092C-   52 45 4D      ; "REM" (attention ce n'est pas un TOKEN)
092F-   20            ; ESPACE
0930-   2A 2A 2A      ; "***"
0933-   20 56 4F
0936-   49 43
0938-   49 20         ; ici on a le message que l'on peut
093A-   4C 45 20
093D-   44
093E-   45 42
0940-   55 54         ; voir dans le listing BASIC
0942-   2C 42 41
0945-   4E 44 45
0948-   20 44 45
094B-   20 50 45
094E-   54
094F-   49 54         ; pas la peine de le re-écrire...
0951-   53
0952-   20 56 4F      ; vous pouvez le voir directement sur
0955-   59 4F 55
0958-   53            ; l'image juste au dessus...
0959-   20 21 21
095C-   21 20
095E-   2A 2A 2A      ; "***"
0961-   00            ; fin de la ligne 2

Ici, on entre dans le vif du sujet avec le royaume du paraître. En effet, alors que la ligne BASIC ne semble contenir qu'un simple REM (avec petit message de la part de QTIPS), il s'avère en fait que ce REM n'existe pas ! Il n'est pas sous forme de TOKEN, c'est juste un message texte. Applesoft ne le reconnaît donc pas. L'essentiel est planqué "derrière" les nombreux CTRL+H qui masquent en fait le vrai listing à l'écran. Le but est de camoufler le GOSUB 7000, unique commande exécutée de la ligne ! Et que trouvons-nous en 7000 ?

7000 POKE 2406,140    ; le contenu de $966 devient $8C.
7001 RETURN           ; $966 concerne directement la mémoire BASIC de la ligne 3

Ligne 03 :

0962-   A4 09         ; adresse mémoire ligne suivante (=$9A4)
0964-   03 00         ; numéro de ligne BASIC =03
0966-   B9 -> 8C      ; le TOKEN POKE devient donc un TOKEN CALL !
0967-   31 36 35 37 36; "16576"
096C-   3A            ; ":"
096D-   B2            ; TOKEN REM
096E-   20 	      ; ESPACE
096F-   08 	      ; et encore du CTRL+H (<-)
0970-   08            ; pour camoufler le CALL d'au-dessus
...
...
097F-   08
0980-   08
0981-   3A            ; ":"
0982-   50 4F 4B 45   ;	"POKE"
0986-   20            ; ESPACE
0987-   33 32 37 36 39; "32769"
098C-   2C 	      ; ","
098D-   50 45 45 4B   ; "PEEK"
0991-   28            ; "("
0992-   36 34 36 39 31; "64691"
0997-	29 	      ; ")"
0998-   3A            ; ":"
0999-   43 41 4C 4C   ; "CALL"
099D-   20 	      ; ESPACE
099E-   33 32 37 36 39; "32769"
09A3-   00            ; fin de ligne

Même principe ici. Les CTRL+H camouflent le CALL 16576. Tout le reste n'est que leurre, ce sont de fausses instructions sous forme ASCII (et non pas des commandes TOKEN). Comme on l'a vu précédemment, comble du luxe, QTIPS a même pris la peine de faire modifier le POKE en CALL par le GOSUB 7000 précédent...

Ligne 04 :

09A4-   B1 09         ; adresse ligne suivante (=$9B1)
09A6-   04 00         ; ligne basic 04
09A8-   3A            ; ":"
09A9-   86            ; TOKEN commande DIM
09AA-   4E 24         ; "N$"
09AC-   28            ; "("
09AD-   33 30         ; "30"
09AF-   29            ; ")"
09B0-   00            ; fin de ligne

Je parlais de luxe juste au-dessus. Encore un signe évident ici avec le " :" rajouté manuellement (et non pas dû comme pour les autres lignes 2 et 3 au camouflage imparfait par CTR+H). C'est juste histoire de brouiller un peu plus les pistes car cette ligne là est une vraie ligne BASIC avec un vrai DIM (30) !

Voilà, à partir de là le programme continue normalement mais nous avons localisé l'essentiel, le CALL 16576, soit $40C0. Il suffit de faire sous Monitor un petit $40C0G pour voir l'image s'afficher et la musique jouer. Une dernière petite chose à propos du programme BASIC... On a vu que les lignes 2 et 3 étaient remplies de fausses instructions (pendant que les vraies s’exécutent en coulisse). Pourquoi l'interpréteur Applesoft ne renvoie aucune erreur quand il rencontre ce garbage là ? C'est justement le but de la commande ON ERROR de la ligne 1 (et du RESUME en ligne 6000). L'illusion est parfaite !

Le Player

Localiser l'adresse (ou presque) du player était la partie la plus importante du défi.
Qu'avons-nous donc en $40C0 ? Pas tout à fait le Player en fait car QTIPS a utilisé une autre ruse, l'utilisation de la page texte ($400) pour y loger son programme. Voyons tout ça :

40C0-   2C 10 C0    BIT   $C010    ; initialisation Clavier
40C3-   2C 57 C0    BIT   $C057    ; mode Hires
40C6-   2C 50 C0    BIT   $C050    ; mode graphique
40C9-   2C 54 C0    BIT   $C054    ; page 1
40CC-   2C 52 C0    BIT   $C052    ; plein écran
40CF-   A0 00       LDY   #$00
40D1-   (74)/ EA    NOP            ; $74 = "double" NOP
40D2-   (A9)/ EA    NOP            ; le A9 est donc shunté
40D3-   B9 00 41    LDA   $4100,Y
40D6-   (74)/EA     NOP            ; idem
40D7-   (85)/EA     NOP
40D8-   99 00 04    STA   $0400,Y  ; déplacement $4100/$41F0 vers $400+
40DB-   A9 00       LDA   #$00     ; on nettoie
40DD-   99 00 41    STA   $4100,Y  ; derrière
40E0-   C8          INY
40E1-   C0 F1       CPY   #$F1     ;
40E3-   D0 EE       BNE   $40D3    ; on boucle
40E5-   A0 00       LDY   #$00     ;
40E7-   B9 F7 40    LDA   $40F7,Y  ; initialisation
40EA-   99 F9 00    STA   $00F9,Y  ; variables pour le player
40ED-   C8          INY
40EE-   C0 07       CPY   #$07
40F0-   D0 F5       BNE   $40E7
40F2-   EA          NOP
40F3-   EA          NOP
40F4-   4C 00 04    JMP   $0400    ; JMP Player !

Petite routine qui fait le déplacement vers la page Texte 1 après avoir initialisé le mode graphique (et déclenché donc l'affichage de l'image d'intro). Une fois ceci fait, on saute en $400 pour lancer la musique en elle-même. Tout le monde aura reconnu à l'oreille une musique issue de Electric Duet. QTIPS ayant développé lui-même un petit player pour ce format, il était intéressant de voir s'il y avait des différences avec celui utilisé ici. Pour info (car finalement, cela a peu d'importance pour le défi), vous trouverez ci-dessous le code ASM des deux players mis côte à côte. À gauche donc, le player du défi (adresse de base en $400) et à droite le générique de QTIPS (adresse de base en $1E00) que l'on peut retrouver sur ses différentes productions (comme Miami Sound Machine). J'ai essayé de mettre face à face les lignes correspondantes pour plus de clarté. On voit que les deux codes sont très proches, QTIPS ayant "juste" rajouté un système complexe d'EOR dans le code même. Data et Player sont ainsi intimement liés (c'est à dire que les données du défi ne pourront pas être utilisées avec le player générique et vis versa...).

0400-   A5 F9       LDA   $F9  ; Data Musique Adresse Lo
0402-   85 01       STA   $01
0404-   A5 FA       LDA   $FA  ; Data Musique Adresse Hi
0406-   85 02       STA   $02
0408-*  20 16 04    JSR   $0416
040B-   2C 00 C0    BIT   $C000
040E-   30 03       BMI   $0413
0410-*  4C 00 04    JMP   $0400
0413-   60          RTS
0414-   EA          NOP
0415-   EA          NOP
0416-   A9 01       LDA   #$01           1E00-   A9 01       LDA   #$01
0418-   85 09       STA   $09            1E02-   85 09       STA   $09
041A-   85 00       STA   $00            1E04-   85 1D       STA   $1D
041C-   48          PHA                  1E06-   48          PHA
041D-   48          PHA                  1E07-   48          PHA
041E-   48          PHA                  1E08-   48          PHA
041F-   D0 21       BNE   $0442          1E09-   D0 15       BNE   $1E20
0421-   C8          INY                  1E0B-   C8          INY
0422-   B1 01       LDA   ($01),Y        1E0C-   B1 1E       LDA   ($1E),Y
0424-   45 FB       EOR   $FB
0426-   85 09       STA   $09            1E0E-   85 09       STA   $09
0428-   C8          INY                  1E10-   C8          INY
0429-   B1 01       LDA   ($01),Y        1E11-   B1 1E       LDA   ($1E),Y
042B-   45 FF       EOR   $FF
042D-   85 00       STA   $00            1E13-   85 1D       STA   $1D
042F-   A5 FE       LDA   $FE
0431-*  8D 38 04    STA   $0438
0434-   A5 01       LDA   $01            1E15-   A5 1E       LDA   $1E
0436-   38          SEC                  1E17-   18          CLC
0437-   E9 13       SBC   #$13           1E18-   69 03       ADC   #$03
0439-*  8D 38 04    STA   $0438
043C-   85 01       STA   $01            1E1A-   85 1E       STA   $1E
043E-   B0 02       BCS   $0442          1E1C-   90 02       BCC   $1E20
0440-   C6 02       DEC   $02            1E1E-   E6 1F       INC   $1F
0442-   A4 FD       LDY   $FD            1E20-   A0 00       LDY   #$00
0444-   B1 01       LDA   ($01),Y        1E22-   B1 1E       LDA   ($1E),Y
0446-   45 FB       EOR   $FB
0448-   C9 01       CMP   #$01           1E24-   C9 01       CMP   #$01
044A-   F0 D5       BEQ   $0421          1E26-   F0 E3       BEQ   $1E0B
044C-   B0 17       BCS   $0465          1E28-   B0 0D       BCS   $1E37
044E-   68          PLA                  1E2A-   68          PLA
044F-   68          PLA                  1E2B-   68          PLA
0450-   68          PLA                  1E2C-   68          PLA
0451-   A2 49       LDX   #$49           1E2D-   A2 49       LDX   #$49
0453-   C8          INY                  1E2F-   C8          INY
0454-   A5 FF       LDA   $FF
0456-*  8D 5C 04    STA   $045C
0459-   B1 01       LDA   ($01),Y        1E30-   B1 1E       LDA   ($1E),Y
045B-   49 25       EOR   #$25
045D-*  8D 5C 04    STA   $045C
0460-   D0 02       BNE   $0464          1E32-   D0 02       BNE   $1E36
0462-   A2 C9       LDX   #$C9           1E34-   A2 C9       LDX   #$C9
0464-   60          RTS                  1E36-   60          RTS
0465-   85 08       STA   $08            1E37-   85 08       STA   $08
0467-*  20 51 04    JSR   $0451          1E39-   20 2D 1E    JSR   $1E2D
046A-*  8E B1 04    STX   $04B1          1E3C-   8E 83 1E    STX   $1E83
046D-   85 06       STA   $06            1E3F-   85 06       STA   $06
046F-   A6 09       LDX   $09            1E41-   A6 09       LDX   $09
0471-   4A          LSR                  1E43-   4A          LSR
0472-   CA          DEX                  1E44-   CA          DEX
0473-   D0 FC       BNE   $0471          1E45-   D0 FC       BNE   $1E43
0475-*  8D AA 04    STA   $04AA          1E47-   8D 7C 1E    STA   $1E7C
0478-*  20 51 04    JSR   $0451          1E4A-   20 2D 1E    JSR   $1E2D
047B-*  8E E9 04    STX   $04E9          1E4D-   8E BB 1E    STX   $1EBB
047E-   85 07       STA   $07            1E50-   85 07       STA   $07
0480-   A6 00       LDX   $00            1E52-   A6 1D       LDX   $1D
0482-   4A          LSR                  1E54-   4A          LSR
0483-   CA          DEX                  1E55-   CA          DEX
0484-   D0 FC       BNE   $0482          1E56-   D0 FC       BNE   $1E54
0486-*  8D E2 04    STA   $04E2          1E58-   8D B4 1E    STA   $1EB4
0489-   68          PLA                  1E5B-   68          PLA
048A-   A8          TAY                  1E5C-   A8          TAY
048B-   68          PLA                  1E5D-   68          PLA
048C-   AA          TAX                  1E5E-   AA          TAX
048D-   68          PLA                  1E5F-   68          PLA
048E-   D0 03       BNE   $0493          1E60-   D0 03       BNE   $1E65
0490-   2C 30 C0    BIT   $C030          1E62-   2C 30 C0    BIT   $C030
0493-   C9 00       CMP   #$00           1E65-   C9 00       CMP   #$00
0495-   30 03       BMI   $049A          1E67-   30 03       BMI   $1E6C
0497-   EA          NOP                  1E69-   EA          NOP
0498-   10 03       BPL   $049D          1E6A-   10 03       BPL   $1E6F
049A-   2C 30 C0    BIT   $C030          1E6C-   2C 30 C0    BIT   $C030
049D-   85 4E       STA   $4E            1E6F-   85 4E       STA   $4E
049F-   2C 00 C0    BIT   $C000          1E71-   2C 00 C0    BIT   $C000
04A2-   30 C0       BMI   $0464          1E74-   30 C0       BMI   $1E36
04A4-   88          DEY                  1E76-   88          DEY
04A5-   D0 02       BNE   $04A9          1E77-   D0 02       BNE   $1E7B
04A7-   F0 06       BEQ   $04AF          1E79-   F0 06       BEQ   $1E81
04A9-   C0 01       CPY   #$01           1E7B-   C0 03       CPY   #$03
04AB-   F0 04       BEQ   $04B1          1E7D-   F0 04       BEQ   $1E83
04AD-   D0 04       BNE   $04B3          1E7F-   D0 04       BNE   $1E85
04AF-   A4 06       LDY   $06            1E81-   A4 06       LDY   $06
04B1-   45 FC       EOR   $FC            1E83-   49 40       EOR   #$40
04B3-   24 4E       BIT   $4E            1E85-   24 4E       BIT   $4E
04B5-   50 07       BVC   $04BE          1E87-   50 07       BVC   $1E90
04B7-   70 00       BVS   $04B9          1E89-   70 00       BVS   $1E8B
04B9-   10 09       BPL   $04C4          1E8B-   10 09       BPL   $1E96
04BB-   EA          NOP                  1E8D-   EA          NOP
04BC-   30 09       BMI   $04C7          1E8E-   30 09       BMI   $1E99
04BE-   EA          NOP                  1E90-   EA          NOP
04BF-   30 03       BMI   $04C4          1E91-   30 03       BMI   $1E96
04C1-   EA          NOP                  1E93-   EA          NOP
04C2-   10 03       BPL   $04C7          1E94-   10 03       BPL   $1E99
04C4-   CD 30 C0    CMP   $C030          1E96-   CD 30 C0    CMP   $C030
04C7-   C6 4F       DEC   $4F            1E99-   C6 4F       DEC   $4F
04C9-   D0 11       BNE   $04DC          1E9B-   D0 11       BNE   $1EAE
04CB-   C6 08       DEC   $08            1E9D-   C6 08       DEC   $08
04CD-   D0 0D       BNE   $04DC          1E9F-   D0 0D       BNE   $1EAE
04CF-   50 03       BVC   $04D4          1EA1-   50 03       BVC   $1EA6
04D1-   2C 30 C0    BIT   $C030          1EA3-   2C 30 C0    BIT   $C030
04D4-   48          PHA                  1EA6-   48          PHA
04D5-   8A          TXA                  1EA7-   8A          TXA
04D6-   48          PHA                  1EA8-   48          PHA
04D7-   98          TYA                  1EA9-   98          TYA
04D8-   48          PHA                  1EAA-   48          PHA
04D9-*  4C 2F 04    JMP   $042F          1EAB-   4C 15 1E    JMP   $1E15
04DC-   CA          DEX                  1EAE-   CA          DEX
04DD-   D0 02       BNE   $04E1          1EAF-   D0 02       BNE   $1EB3
04DF-   F0 06       BEQ   $04E7          1EB1-   F0 06       BEQ   $1EB9
04E1-   E4 FD       CPX   $FD            1EB3-   E0 01       CPX   #$01
04E3-   F0 04       BEQ   $04E9          1EB5-   F0 04       BEQ   $1EBB
04E5-   D0 04       BNE   $04EB          1EB7-   D0 04       BNE   $1EBD
04E7-   A6 07       LDX   $07            1EB9-   A6 07       LDX   $07
04E9-   C9 80       CMP   #$80           1EBB-   49 80       EOR   #$80
04EB-   70 A3       BVS   $0490          1EBD-   70 A3       BVS   $1E62
04ED-   EA          NOP                  1EBF-   EA          NOP
04EE-   50 A3       BVC   $0493          1EC0-   50 A3       BVC   $1E65

Bien, nous avons donc le Player, on sait qu'un $40C0G lancera la musique. Il faut maintenant localiser les Data. On sait que l'adresse de départ provient de $F9 et $FA, deux variables initialisées juste après la routine de déplacement vers $400 du Player. Problème : sur cette version spécifique, le Buffer Data ne va pas vers l'avant mais en arrière... On peut partir de $5FFD ($FA = 5F et $F9 = $FD) et remonter pour trouver manuellement le départ des data en mémoire.
Mais on peut aussi légèrement modifier le Player en $40B (donc en $410B, avant le déplacement) pour y mettre un $60 (RTS). On récupérera ainsi la main après une lecture complète de la musique juste avant qu'elle ne reboucle. Il suffira alors de checker le contenu de $01 et $02 pour trouver l'adresse de "fin" des Data (qui sera en fait l'adresse de "début" en mémoire... puisqu'on va en arrière... c'est pourtant clair non ?). Avec ce petit exercice, on arrive à trouver la valeur $5C7F.

Il ne reste plus alors qu'à tout recoller, Player et Data, ajouter une petite routine qui initialise les variables indispensables (de $F9 à $FF) et, cerise sur le gâteau, "reloger" le tout en dehors de la page Texte afin de rendre la routine un peu plus utilisable. Il va falloir modifier manuellement les différents STA/STX qui pointent vers la page $04 ainsi que les quelques JSR qui font de même. Rien de compliqué, il faut juste prendre son temps et bien recalculer les nouvelles valeurs. Les lignes à modifier sont signalées par un "*" dans le code ci-dessus (partie gauche). Concrètement, vous calculez le déplacement entre $400 et la nouvelle adresse que vous avez choisie pour le Player et vous ajoutez cette valeur à l'adresse pointée dans le code. Exemple :
- vous voulez mettre votre Player en $1020 (pensez à laisser avant la place nécessaire pour le petit code qui initialisera les variables). Le déplacement vaut donc $1020-$400 soit $C20. Il faudra donc ajouter $C20 à chaque adresse qui pointait vers un $400+.
- exemple pour la ligne en $408 : JSR $416. Cette ligne après déplacement sera en : $1028. Et le JSR $416 devra devenir un JSR $1036. Et ainsi de suite... Pour "reloger" le code du player, laissez faire le programme en $40C0 en remplaçant juste le STA $0400,Y (en $40D8) par l'adresse choisie.

Il ne reste plus ensuite qu'à déplacer les data "musique" (qui sont entre $5C7F et $5FFF) juste à la suite du player. Et sauvez le tout...

Quelques petites remarques pour finir :

  • si on supprime une ligne en début du programme BASIC (comme la 0 par exemple), plus rien ne marche. Logique, tout se retrouve décalé en mémoire qui est réorganisée par Applesoft en temps réel et le POKE $966,$8C en ligne 7000 ne modifiera plus du tout un POKE en CALL mais plantera alors allègrement le programme.
  • nulle trace dans le programme BASIC du chargement de l'image et de la musique. Tout est fait lors du boot en accès direct visiblement.
  • sur le disque Miami Sound Machine III (autre production QTIPS),  il y a 3 fichiers texte de résolution du défi écrits par Astraban, Captain Crack et Jojo. Comme d'habitude, je ne les ai lu qu'après avoir écrit ce texte proposant ma propre solution.  Ils sont toutefois très intéressants car ils décrivent chacun une approche différente. J'ai particulièrement apprécié l'efficacité froide d'un Captain Crack qui, en utilisant le boot tracing, ne s'occupe même pas du programme BASIC. Mais aussi l'astuce d'un Astraban avec la commande SPEED=1 qui ralentit la vitesse d'affichage à l'écran et permet de voir en temps réel les CTRL+H en action masquant les vraies instructions... Je vous invite fortement à lire ces textes en complément du mien. Et je vous rassure, ils sont beaucoup moins bavards que moi... Cela démontre en tout cas qu'il n'y a jamais qu'une solution et que différentes approches sont toujours possibles.

 

Pour finir, voici en téléchargement :

Et maintenant, place à  la musique ! 

Clip audio : Le lecteur Adobe Flash (version 9 ou plus) est nécessaire pour la lecture de ce clip audio. Téléchargez la dernière version ici. Vous devez aussi avoir JavaScript activé dans votre navigateur.