Page 1 sur 1

[eZ80] Algorithme de Bresenham : optimisation

Message non luPosté: 12 Avr 2016, 17:43
de grosged
Comme prévu, j'adapte en assembleur ce que j'avais commencé à élaborer en Basic ;)

Pour l'instant, je me borne à tracer un segment [(x1,y1),(x2,y2)] dans ce cas de figure:
x1 < x2
y1 < y2
(x2 - x1) > (y2 - y1) c'est-à-dire: Δx > Δy

En guise de test, je fais un Line(0,0)-(300,19) ... et ça marche !!! =D

Cela n'est qu'une première ébauche (il manque, en début de programme les calculs nécessaires pour obtenir Δx et Δy , etc...)
Code: Tout sélectionner
.nolist
#include "ti84pce.inc"
.list
.org userMem-2
.db tExtTok,tAsm84CeCmp
.assume ADL=1
           
            di                ; Interdit les interruptions

            ld a,$27          ; Passe en mode graphique 8bpp
            ld ($e30018),a       ; Idéal car dans ce mode,
            ld hl,$e40000       ; 1 pixel = 1 octet
            ld de,$d40000       ; efface l'écran
            ld bc,76800       ; (méthode rapide)
            ldir             
                           ; On va maintenant effectué comme un Line(0,0)-(300,19)
            exx             ; Pour l'instant, j'inscris des  valeurs précalculées
            push bc    ; (Dans la version à venir, le prog effectuera les calculs)   
            push de          ; (j'avais trop hâte de vérifier son bon fonctionnement !)
            push hl          ; On préserve les registres'
            or a             ; on met le drapeau "carry" à zéro
            sbc hl,hl         ; HL' = variable d'erreur E (pour démarrer, à zéro)
            ld bc,-600          ; BC' = -2Δx
            ld de,300          ; DE' = Δx
            exx      ; on revient vers les registres classiques
            ld (OldSP+1),sp       ; on préserve la pile
            ld sp,262          ; SP = Δx-2Δy
            ld hl,$d40000       ; HL = pointeur en zone-écran correspondant au point(x1,y1)
            ld bc,320         ; BC = largeur de l'écran (en octets)
            ld de,300          ; nb de points à afficher

            jr Debut          ; Comme on commence par afficher le point (x1,y1)
                           ; part directement dans le coeur de la boucle principale
B_Boucle:   dec de             ; décremente le nb de point à afficher
         exx             ; bascule dans les registres '
         sbc hl,sp          ; E < Δx-2Δy   ?
         jr nc,Evite         ; Oui?..Alors
         exx             ; on rebascule en registres classiques
         add hl,bc          ; descend d'1 cran le pointeur en mémoire-écran
         exx             ; on revient vers les registres'
         add hl,bc          ; E = E - 2Δx
Evite:      add hl,de    ; E = E + 2Δy + Δx-2Δy  (par rapport au test effectué plus haut!)
         exx             ; revient vers les registres classiques
         inc hl       ; décale le pointeur en mémoire-écran d'1 octet (=1 pixel) vers la droite
Debut:      ld (hl),5          ; pour y afficher un point
         ld a,d             ; Avons-nous affiché tous les points du segment ?
         or e             ; Si on n'est pas à zéro
         jr nz,B_Boucle       ; Alors on boucle

OldSP:      ld sp,0          ; rétablit la pile
         exx             ; ainsi que les registres'
         pop hl             ; ...
         pop de
         pop bc
         exx
         ei                ; autorise de nouveau les interruptions
         ret               ; Terminé!
                        ; Volontairement , je reste en mode 8bpp, afin de voir le résultat.