Revenir au plan du site

Export de l'intro pour support CPC

Pour adapter notre programme et qu'il soit exécutable depuis le Basic, assez peu de choses à faire mais en premier lieu, il faut dézinguer le système!
ld hl,#C9FB : ld (#38),hl ; écraser le vecteur d'interruption

Mais j'y pense, nous n'utilisons pas les interruptions dans notre programme, alors il y a encore plus court pour dire au système d'arrêter ses âneries :)
di ; couper les interruptions

Je vous conseille néanmoins de cumuler les deux au cas où vous prendrait l'envie de vous servir des interruptions à un moment ou un autre.

Pour continuer et ça sera notre dernière adaptation, il faut que les données de l'écran soit contigiuës au programme, pour rappel le système utilise la zone #A000-#BFFF et il n'est pas possible de charger un fichier au dela du début de cette zone. On copiera donc notre écran de là où il est, vers #C000.
ld hl,donnees_ecran
ld de,#C000
ld bc,16384
ldir

Et si on compressait? RASM est capable de cruncher à la volée des données et même du code!
; plutôt que
org #C000 : incbin 'screen160.bin'
; on écrirait
donnees_ecran_compresses inczx0 'screen160.bin'

Et on utilisera la routine de décompression fournie avec RASM (dans le répertoire decrunch)
ld hl,donnees_ecran
ld de,#C000
call unzx0
...
; en fin de code
include 'dzx0_standard.asm'
unzx0 dzx0_standard (void)

Enfin, vous placez la directive BUILDTAPE au début du programme pour enregistrer un fichier K7 et tout à la fin du programme la ligne suivante pour créer une disquette. L'assemblage produira deux fichiers. Un DSK et un CDT.
save 'intro.bin',#100,$-#100,DSK,'IntroNoel2024.dsk'

Allez, au code!
BUILDTAPE ; produire un fichier K7
ORG #100 : RUN #100

di : ld hl,#C9FB : ld (#38),hl
ld sp,#100
ld bc,#7F00+%10001100+%00 : out (c),c ; MODE 0
ld hl,palette : ld bc,#7F00
setPalette out (c),c : inc c : inc b : outi : ld a,(hl) : or a : jr nz,setPalette
ld hl,donnees_ecran
ld de,#C000
call unzx0 ; decrunch des données vers l'écran

LaBoucle
call waitVBLstart
ld iy,yeuxOuverts : pokeYeux=$-2 : call GestionEtape
ld iy,doigts1 : pokeDoigts=$-2 : call GestionEtape

ld hl,#C000+3 : call ScrollBande
ld de,#C000+3+24*80+7*#800 ; ligne 199 en dessous
call DisplayCharLine
ld hl,#C000+72 : call ScrollBande
ld hl,#C000+3+10*80 : ld de,#C000+72+24*80+7*#800 : ldi : ldi : ldi : ldi ; copie retardée
jr LaBoucle
;---
waitVBLstart
ld b,#F5
.loop in a,(c) : rra : jr c,.loop ; attendre l'absence de VBL
waitVBL
ld b,#F5
.loop in a,(c) : rra : jr nc,.loop ; attendre la VBL
ret
;---
struct etape
duree defb
sprdata defw
adrecran defw
hauteur defb
etapeSuivante defw
pokeEtape defw
dureeMin defb
dureeMod defb
endstruct
;---
yeuxOuverts
defb 1
defw yeuxFermesdata
defw #C000+80*7+#800*6+40
defb 21
defw yeuxFermes
defw pokeYeux
defb 4,3

yeuxFermes
defb 1
defw yeuxOuvertsdata
defw #C000+80*7+#800*6+40
defb 21
defw yeuxOuverts
defw pokeYeux
defb 30,31

doigts1
defb 1
defw doigts2data
defw #C000+80*13+32+#800*2
defb 30
defw doigts2
defw pokeDoigts
defb 15,15

doigts2
defb 1
defw doigts1data
defw #C000+80*13+32+#800*2
defb 30
defw doigts1
defw pokeDoigts
defb 15,15

;---
DisplayCharLine
.currentData ld hl,daFonte : ldi 4 : ld (.currentData+1),hl ; copier la ligne du char
.currentStep ld a,17 : dec a : jr z,.currentChar ; décompter les lignes du sprite
ld (.currentStep+1),a : ret
;
.currentChar ld hl,LeTexte : inc hl : ld (.currentChar+1),hl
ld a,17 : ld (.currentStep+1),a ; réarmer le compteur de lignes
ld a,(hl) : cp 255 : jr nz,.texteOK ; choper le nouveau caractère
ld hl,LeTexte : ld a,(hl) : ld (.currentChar+1),hl ; reinit du texte
.texteOK ld l,a : ld h,0 : ld de,hl
add hl,hl : add hl,hl : add hl,hl : add hl,hl ; x16
add hl,de ; x17
add hl,hl : add hl,hl ; x17 x4
ld de,daFonte : add hl,de ; données de la lettre en cours
ld (.currentData+1),hl ; qu'on remet dans la routine de copie
ret

GestionEtape
; IY=etape
ld a,(iy+etape.duree) : dec a : ld (iy+etape.duree),a : ret nz ; durée pas terminée, aurevoir
ld hl,(iy+etape.sprdata)
ld de,(iy+etape.adrecran)
ld a,(iy+etape.hauteur) : ld xl,a
call AfficheSprite
ld de,(iy+etape.etapeSuivante)
ld hl,(iy+etape.pokeEtape) : ld (hl),e : inc hl : ld (hl),d
ld c,(iy+etape.dureeMod) : ld a,r : and c : add (iy+etape.dureeMin) ; A=nouvelle durée
ld (de),a ; nouvelle duree de la nouvelle structure
ret
;---
AfficheSprite
; HL=données du sprite
; DE=adresse écran en haut à gauche du sprite
; XL=hauteur du sprite
.afficheLigne push de : ldi 12 : pop de
ld a,d : add 8 : ld d,a ; ajouter #800 à DE
jr nc,.nextLine ; pas de débordement, on est toujours dans le même bloc de lignes
ld a,80  : add e : ld e,a ; on ajoute 80 (largeur d'une ligne en octets) pour passer au bloc suivant
ld a,#C0 : adc d : ld d,a ; et on enlève #4000 (additionner #C000 c'est comme enlever #4000)
.nextLine
dec xl
jr nz,.afficheLigne
ret
;---
ScrollBande
; HL=adresse du coin supérieur gauche de la colonne à scroller
ld de,hl : ld a,h : add 8 : ld h,a ; ligne suivante
ld xl,100
.scroll200
ldi : ldi : ldi : ld a,(hl) : ld (de),a ; copier 4 octets au dessus
ld d,h ; la ligne courante devient la nouvelle destination
ld a,h : add 8 : ld h,a ; on descend la ligne courante
jr nc,.okBlock : ld bc,80-#4000 : add hl,bc : .okBlock
; nos pointeurs sont maintenant sur la droite, on copie à l'envers!
ldd : ldd : ldd : ld a,(hl) : ld (de),a
ld de,hl ; courante devient destination, on copie aussi le poids faible en cas d'ajustement de bloc
ld a,h : add 8 : ld h,a ; on descend la ligne courante, on est sûr de rester dans le bloc
dec xl : jr nz,.scroll200
ret
;---
palette defb #54,#5C,#44,#56,#46,#4C,#55,#57,#45,#4E,#5F,#59,#4A,#43,#5B,#4B
border defb #54,0
align 4
daFonte incbin 'daFonte.bin'
doigts1data incbin 'doigts1.bin'
doigts2data incbin 'doigts2.bin'
yeuxOuvertsdata incbin 'yeuxOuverts.bin'
yeuxFermesdata incbin 'yeuxFermes.bin'
; la commande Charset permet de 'renommer' les valeurs ASCII, ici on repart de zéro au lieu de 32
charset ' !"###&\'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz',0
LeTexte defb ' alors qui est le meilleur? ',255
charset

donnees_ecran inczx0 'screen160.bin'
include 'dzx0_standard.asm'
unzx0 dzx0_standard (void)

save 'intro.bin',#100,$-#100,DSK,'IntroNoel2024.dsk'

Et voici notre intro compressée à hauteur de 12K :)