Inscription : 05 Avr 2012, 08:02 Message(s) : 110 Localisation : Sur terre, mais souvent dans les nuages !
Salut à tous,
Je fait appel à vous car je ne souhaite pas me prendre trop la tête avec l'asm (la y'en a qui vont s'en donner fond )
J'ai ce code pour copier un sprite, on y passe une adresse de départ écran ou copier, l'adresse du sprite qui est en mémoire de façon linéaire largeur et hauteur, est t'il correcte en terme de temps machine utilisé ?
Code :
; HL adresse ecran ; C Largeur ; B hauteur ; DE adrese du sprite
B_Hauteur: PUSH BC LD B,C PUSH HL B_Largeur: LD A,(DE) LD (HL),A INC DE INC HL DJNZ B_Largeur POP HL LD A,H ADD #0x08 LD H,A SUB #0xC0 JP NC, Ligne LD BC, #0xC050 ADD HL,BC Ligne: POP BC DJNZ B_Hauteur
Je voudrais partir de ce code pour faire l'inverse, copier une zone écran en mémoire de façon linéaire en y passent l'adresse mémoire écran, l'adresse mémoire ou seront copier les données, la largeur et la hauteur.
Autre question, j'ai fait ces deux code pour la copie de mémoire à mémoire, en lisent un peut tout sur le net, il faut mieux utiliser LDIR ou LDI ?? En gros lequel des deux est vraiment la plus rapide ?
Code :
Copie1: ;HL = adresse de départ ;DE = adresse de destination ;BC = nombre d’octets
LDIR ; Recopie de bloc ...
Copie2: ; HL = adresse de départ ; DE = adresse de destination ; BC = nombre d’octets + 1
BOUCLE: LDI ; Copie une donnée JP PO,FIN ; Sort de la boucle si BC = 1 JP BOUCLE ; Sinon continue FIN: ...
La routine d'affichage de sprite est classique et tout à fait correcte. Tu peux l'améliorer un peu au niveau vitesse si tes sprites tiennent dans des fenêtres mémoire de 256 octets. Auquel cas, au lieu de faire un INC DE, tu peux utiliser INC E.
Tu peux aussi utiliser LDI en lieu et place de LD A,(DE) LD (HL),A INC HL INC DE en utilisant le registre A comme compteur de boucle. Le gain sera intéressant.
Inscription : 12 Juin 2008, 20:29 Message(s) : 1709
L'intérêt d'un LDIR c'est que la boucle de copie est incluse dans cette instruction (transfert bc octet de hl vers de avec à la fin bc =0, hl=hl+bc et de=de+bc). pour utiliser LDI qui est plus rapide, il faut que la largeur soit toujours la même. sinon le test de fin sera supérieur à un LDIR !
ld a,(hl);ld (de),a;inc hl:inc de peut effectivement être remplacé par un LDI (attention si on se sert de b ou c pour une boucle, il faut incrémenter bc (ou c si b différent de 0 avant).
d'une façon générale, c'est valable pour tout les langages, il faut optimiser en premier les boucles qui prennent le plus de temps machine !
l'idéal est donc de coder ton programme, de le tester et d'en être pleinement satisfait (=un programmeur heureux) : ensuite si tu as un pb de perf, tu optimises d'abord les boucles (en les éliminants) dans la limite de la mémoire dispo ! ex : (j'ai compté le temps machine en nop pour que tu comprennes le gain)
ld hl,&c000 ; 3 ld de,&4000; 3 ldi ; 5 ldi ; 5 ldi ; 5 total : 21 j'ai gagné l'init de bc (-3) + la boucle du ldir pour deux octets (-2) sinon, si j'ai pas besoin d'inc hl et de au dernier ldi, je peux remplacer par ld a,(hl), ld (de),a et j'ai gagné encore 1
en asm, on peut écrire cela pour répéter 3 fois LDI (utile quand tu en as bcp plus ) : REPEAT 3 LDI REND
Les bons et vrais codeurs te diront qu'il faut écrire le code en étant déjà optimisé à fond : mais je pense que c'est une vieille légende cpcienne !!!
Utilisateur(s) parcourant ce forum : Aucun utilisateur inscrit et 49 invité(s)
Vous ne pouvez pas publier de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas insérer de pièces jointes dans ce forum