Scrolling vertical facile avec l'ASICDe la même façon que pour le [scrolling horizontal], l'ASIC propose une aide au scrolling vertical. Ça se passe toujours au niveau du SSR qui contient les informations de retard pour la verticale et l'horizontale. Rappel sur le SSR (Soft Scroll Register) de l'ASIC Pour scroller en vertical, on fera changer le SSR de #10 en #10 (il est possible de mélanger avec l'horizontale, je simplifie). Les valeurs possibles seront 0, #10, #20, #30, ... , #60 et #70
| Soft Scroll Register (registre de scroll) - Adresse dans la page ASIC = #6804 | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | Si activé, continue d'afficher le border pendant 2 octets | Décalage vertical vers le haut(de 0 à 7) | Décalage horizontal vers la droite (de 0 à 15)* |
Voici un déroulé des valeurs CRTC+SSR lors du scrolling de l'écran (ça fonctionne dans les deux sens) Note : le scrolling CPC au registre 5 n'est pas évoqué dans ce tableau, ne brûlons pas les étapes ;)
| Étapes de scrolling |
|---|
| position Y | scroll CPC | scroll ASIC + SSR |
|---|
| 0 | CRTC Adr = #0000 | CRTC Adr = #0000 SSR = #00 | | 1 | | CRTC Adr = #0000 SSR = #10 | | 2 | | CRTC Adr = #0000 SSR = #20 | | 3 | | CRTC Adr = #0000 SSR = #30 | | 3 | | CRTC Adr = #0000 SSR = #40 | | 5 | | CRTC Adr = #0000 SSR = #50 | | 6 | | CRTC Adr = #0000 SSR = #60 | | 7 | | CRTC Adr = #0000 SSR = #70 | | 8 | CRTC Adr = largeur/2 | CRTC Adr = largeur/2 SSR = #00 | | 9 | | CRTC Adr = largeur/2 SSR = #10 | | ... | ... | ... |
À la verticale, les contraintes d'affichage sont différentes, plus souples qu'à l'horizontale. Sur un scrolling horizontal il est plus fastidieux de répartir la charge d'affichage entre les différentes étapes (celle inévitable où il faut rafraichir la colonne entière (même si un seul pixel de cette colonne est visible) et les autres ou on se contente de changer le registre, il est possible de fragmenter l'affichage de la colonne). Sur le scrolling horizontal, on affiche autant de lignes que le déplacement demandé, il n'y a pas d'étape sans affichage. Pour cet exemple, nous allons utiliser une [TileMap] qu'on fera reboucler. Si vous avez suivi le scrolling horizontal, il n'y a aucun problème avec cet exemple car l'ASIC estd'une aide précieuse pour le scrolling, on aura juste changé quels bits du SSR on incrémente. J'utilise toujours mon outil de conversion convgeneric qui va analyser la map globale et fabriquer l'atlas de tiles ainsi que la tileMap. convgeneric.exe -m 0 -g -tiles -size 8x16 Map16.pngJe récupère toutes les informations de l'outil (téléchargez [Map16.bin] et [Map16.tilemap] paletteplus: defw #213,#231,#223,#333,#342,#443,#453,#554,#564,#664,#684,#777,#8A4,#AD6,#CD8,#FFE 304 sprites extracted => ça, ça veut dire qu'on aura une tileMap 16 bits et non 8 bits ;) et le fichier tilemap contenant les DEFW des tuilesÀ titre informatif, l'outil exporte l'atlas utilisé pour la tileMap, cela permet parfois d'optimiser son export.
Par exemple, je pouvais avoir une tileMap avec moins de 256 sprites mais la conséquence aurait été d'augmenter la quantité graphiques de tuiles. L'outil convgeneric permet de tester différentes combinaisons de tuiles, charge à vous d'optimiser votre affichage selon le niveau (ou pas). Quoi qu'il en soit, convgeneric ne va pas limiter un atlas de tuiles à 256 tuiles, les limites ne servent à rien :p Un dernier mot sur le formatage écran choisi, comme notre map faisait 112 pixels de large (56 octets), cela nous permet de nous étaler verticalement sur les 272 lignes du moniteur (16384/56=292) BUILDSNA : BANKSET 0 SNASET CPC_TYPE,4 ; modèle 6128+ conseillé ORG #100 : RUN #100 ;*** RMR2 tags + macro *** ASICOFF equ 0 : ROM0000 equ 0 : ROM4000 equ %01000 : ROM8000 equ %10000 : ASICON equ %11000ROM0 equ 0 : ROM1 equ 1 : ROM2 equ 2 : ROM3 equ 3 : ROM4 equ 4 : ROM5 equ 5 : ROM6 equ 6 : ROM7 equ 7 macro RMR2 tags ld a,{tags}+%10100000 ld b,#7F out (c),a mendld bc,#7F00+%10001100+%00 : out (c),c ; MODE 0 call UnlockAsic : RMR2 ASICON ld hl,palettePlus : ld de,#6400 : ld bc,32 : ldir : ld hl,#000 : ld (#6420),hl ; +border noir ld bc,#BC00+1 : out (c),c : ld bc,#BD00+28 : out (c),c ; Notre map fait 112 pixels de large, adaptez selon VOS besoins ld bc,#BC00+2 : out (c),c : ld bc,#BD00+39 : out (c),c ; Centrer l'écran en X ld bc,#BC00+6 : out (c),c : ld bc,#BD00+34 : out (c),c ; Hauteur de l'écran visible en lignes de caractères ld bc,#BC00+7 : out (c),c : ld bc,#BD00+35 : out (c),c ; Centrer l'écran en Y ld bc,#BC00+12 : out (c),c : ld bc,#BD30 : out (c),c ; adresse par défaut ld bc,#BC00+13 : out (c),c : ld bc,#BD00 : out (c),c LaBoucle call WaitVBL RMR2 ASICON : ld hl,#6804 ; activer la page ASIC, précharger l'adresse du SSR ld a,0 : decalageCourant=$-1 : add #10 : and #70 : ld (decalageCourant),a : ld (hl),a ; on incrémente le décalage vertical ; si on a rebouclé de #70 à #00, alors le flag Z a été monté par le AND #70 jr nz,pasCRTC ld hl,0 : adresseCRTCcourante=$-2 : ld bc,28 : add hl,bc : res 2,h : ld (adresseCRTCcourante),hl ld bc,#BC00+12 : out (c),c : inc b : ld a,h : or #30 : out (c),a : dec b : inc c : out (c),c : inc b : out (c),l pasCRTC RMR2 ASICOFF ; on ferme la page puisqu'on ne la nécessite plus et que nos données sous dessous! ; nos tiles font 8x16, il faut gérer le 'curseur' à l'intérieur des tiles et on en a 14 en largeur... ld hl,(adresseTuileEcran) : ld (adresseTuileCourante),hl ld ix,tileMap : adresseTileMap=$-2 ld b,14 ; on a 14 tuiles à parcourir AfficheLigneTuile exx ; on met le compteur dans les registres secondaires ld hl,(ix+0) : inc lx : inc ix ; index de la tuile 16 bits car +256 tuiles ; HL = index x 64 / au lieu de décaler 6 fois vers la gauche, je décale deux fois à droite et je permute les registres (équivalent à 8 décalages - 2) xor a : srl hl : rra : srl hl : rra : ld h,l : ld l,a ld de,tuiles : add hl,de ; HL=adresse de la tuile courante ld a,(ligneTuileCourante) : add a : add a ; ligne x 4 add l : ld l,a : ld a,h : adc 0 : ld h,a ; c'est vraiment pas optimisé tout ce code :p ld de,(adresseTuileCourante) ; afficher la ligne courante de la tuile courante ldi 4 ; copie de la largeur de la tuile, à la bonne ligne ; besoin impératif d'ajuster DE au cas où on se retrouve sur le rebouclage de la ligne de bloc! ; si la partie de l'adresse correspondant à la position dans le bloc (0-#7FF) est nulle, alors on vient de reboucler ld a,d : and 7 : or e : jr nz,.pasDeRebouclage : ld a,d : sub 8 : ld d,a : .pasDeRebouclage ld (adresseTuileCourante),de ; on garde la position exx djnz AfficheLigneTuile ; ligne de tuiles terminée, on prépare la prochaine adresse, ligne en dessous! ld hl,(adresseTuileEcran) : ld a,h : add 8 : ld h,a : jr nc,.novf ld a,56 : add l : ld l,a ld a,#C0 : adc h : ld h,a res 3,h ; rebouclage de bloc en plein début de ligne, ça PEUT arriver .novf ld (adresseTuileEcran),hl ; prêt pour la nouvelle ligne ld a,(ligneTuileCourante) : inc a : and 15 : ld (ligneTuileCourante),a : jr nz,.memesTuiles ld hl,(adresseTileMap) : ld de,14*2 : add hl,de : ld (adresseTileMap),hl ; changer de ligne sur la tileMap ld a,(hl) : inc a : jr nz,.memesTuiles : inc l : ld a,(hl) : inc a : jr nz,.memesTuiles ; test du marqueur de fin ld hl,tileMap : ld (adresseTileMap),hl ; Rebouclage de la tileMap ! .memesTuiles jp LaBoucle UnlockAsic ld bc,#BCFF out (c),c out (c),0 ld hl,%1001000011101010 .loop out (c),c ld a,h:rlca:ld h,l:ld l,a srl c:res 3,c and #88 or c ld c,a cp #4D jr nz,.loop ld a,#CD out (c),a : out (c),a ret WaitVBL ld b,#F5 : noVBL in a,(c) : rra : jr c,noVBL VBL in a,(c) : rra : jr nc,VBL : ret palettePlus defw #213,#231,#223,#333,#342,#443,#453,#554,#564,#664,#684,#777,#8A4,#AD6,#CD8,#FFE adresseTuileEcran defw #C000+56*34 ; avant le premier scroll, cette adresse correspond à la 272 ligne (hors écran, 1 ligne dessous) adresseTuileCourante defw 0 ligneTuileCourante defb 0 tuiles incbin 'Map16.bin' align 2 : tileMap include 'Map16.tilemap' : defw #FFFF ; marqueur de finC'était un peu fastidieux car on n'a pas choisi la facilité avec un écran de 64 octets de large, le notre fait 56 octets, obligeant à ajuster pour le rebouclage de bloc. Hey! Au moins vous avez une méthode pour gérerproprement ce rebouclage (et on parlera de moyens de l'optimiser plus tard). 
Roudoudou CPCrulez[Content Management System] v8.732-desktop/c Page créée en 060 millisecondes et consultée 47 foisL'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko. |
|