1

Salut à tous!
Je débute en asm, donc j'aurais besoin de votre aide et de vos conseils...
Voilà mon premier prog:
.nolist
	#INCLUDE "ti83plus.inc"
        #INCLUDE "ion.inc"
	#DEFINE  ProgStart    $9D95
	_clr =4BD0                   ;GrBufClr (n'existait pas pour le compilo on calc) => J'ai le droit de le placer là?
        .list
        .org    progstart-2
        .db     $BB,6D
        ret		

        jr      nc,put
	.db "Mouvement",0

put:
	ld b,16
	ld a,(X)
	ld hl,(Y)
	ld c,2
	ld ix,sprite
	call ilargesprite
	call ifastcopy

getkey:
	ld a,FEh
	out (1),a
	in a,(1)
	cp 254
	jr z,bas
	cp 253
	jr z,gauche
	cp 251
	jr z,droite
	cp 247
	jr z,haut
	ld a,FDh
	out (1),a
	in a,(1)
	cp 191
	ret z
	jr getkey

bas:
	ld a,(Y)
	cp 40
	jr z,getkey
	bcall clr
	inc a
	ld (Y),a
	jp put
gauche:
	ld a,(X)
	cp 1
	jr z,getkey
	bcall clr
	dec a
	ld (X),a
	jp put
droite:
	ld a,(X)
	cp 60
	jr z,getkey
	bcall clr
	inc a
	ld (X),a
	jp put
haut:
	ld a,(Y)
	cp 1
	jr z,getkey
	bcall clr
	dec a
	ld (Y),a
	jp put

sprite:
	.db 11111111b,11111111b
	.db 10000000b,00000000b
	.db 10000000b,00000000b
	.db 10111111b,00111110b
	.db 10000000b,00000000b
	.db 10001000b,00001000b
	.db 10010100b,00010100b
	.db 10100010b,00100010b
	.db 10000000b,00000000b
	.db 10000001b,00000000b
	.db 10000001b,00000000b
	.db 10000000b,00000000b
	.db 10010000b,00001000b
	.db 10001000b,00010000b
	.db 10000111b,11100000b
	.db 10000000b,00000000b

X:
	.db 20
Y:
	.db 20
	ret

.end
.end


Prog compilé: Fichier joint : A3.8xp
Le but de ce programme est juste de balader une image sur l'écran.
La syntaxe (notament du header) est peut-être fausse, parce que je programme on calc.
Le problème, c'est que ce programme est super lent (rien à voir avec Tiny carZ et autre)...
Donc: comment le faire plus rapide??? Comment l'améliorer?
Merci beaucoup.

2

C'est déjà bien, mais pour que ton header fasse 'plus propre', tu devrait définir '_clr' comme pour ProgStart, et puis X et Y autant les définires dans le headers eux aussi grâce au Saferam :

.nolist 
#include	"ion.inc"			; Inclut juste Ion.inc, pas besoin de ti83plus.inc 
#define		X		Saferam1	; C'est mieu de définir tes variable ici 
#define		Y		Saferam1+1	; avec les Saferam 
 
;Groupe1	:	0feh			; Perso j'ai toujours définit les touches ici pour 
kDown		.equ	254			; le direct input, ça rend le code plus lisible. 
kLeft		.equ	253 
kRight		.equ	251 
kUp		.equ	247 
 
;Groupe2	:	0fdh 
kEnter		.equ	254 
kClear		.equ	191 
 
.list 
 
#ifdef TI83P 
	.org ProgStart-2 
	.db $bb,$6d 
#else  
	.org ProgStart 
#endif 
 
	ret 
	jr nc,Start 
.db "Mouvement",0 
 
Start: 
	ld a,20					; On définit les coordonnées 
	ld (X),a 
	ld (Y),a 
 
Put: 
	bcall(_grbufclr)
	ld a,(Y)				; Là au lieu d'utilise 'hl' utilise que 'l' 
	ld l,a 
	ld a,(X) 
	ld c,2 
	ld b,16 
	ld ix,sprite 
	call ionLargeSprite
	call ionFastCopy 
 
getkey: 
	ld a,0feh 
	out (1),a 
	in a,(1) 
 
	cp kDown				; Définit dans l'header 
	push af					; Les 'push af' servent à garder la valeur de a en la mettant 
	jr z,bas				; dans la pile, ce qui permet de pouvoir appuyer sur plusieurs 
	pop af					; touches à la fois  :)  
	cp kLeft				; Idem 
	push af 
	jr z,gauche 
	pop af 
	cp kRight				; Idem 
	push af 
	jr z,droite 
	pop af 
	cp kUp					; Idem 
	push af 
	jr z,haut 
	pop af 
 
	ld a,0fdh 
	out (1),a 
	in a,(1) 
 
	cp kClear 
	ret z 
	jr getkey 
 
bas: 
	ld a,(Y) 
	cp 48 
	jr z,getkey 
	inc a 
	ld (Y),a 
	jp put 
 
gauche: 
	ld a,(X) 
	cp 0 
	jr z,getkey
	dec a 
	ld (X),a 
	jp put 
 
droite: 
	ld a,(X) 
	cp 80 
	jr z,getkey 
	inc a 
	ld (X),a 
	jp put 
 
haut: 
	ld a,(Y) 
	cp 0 
	jr z,getkey
	dec a 
	ld (Y),a 
	jp put 
 
sprite: 
	.db 11111111b,11111111b 
	.db 10000000b,00000000b 
	.db 10000000b,00000000b 
	.db 10111111b,00111110b 
	.db 10000000b,00000000b 
	.db 10001000b,00001000b 
	.db 10010100b,00010100b 
	.db 10100010b,00100010b 
	.db 10000000b,00000000b 
	.db 10000001b,00000000b 
	.db 10000001b,00000000b 
	.db 10000000b,00000000b 
	.db 10010000b,00001000b 
	.db 10001000b,00010000b 
	.db 10000111b,11100000b 
	.db 10000000b,00000000b 
 
.end  
END


(Par contre t'avais mis un 'ret' à la fin, mais ça sert à rien du tout smile ).

Et sinon j'ai pas tester mais ça devrait être bon, j'ai aussi 'agrandit' les limites de déplacement et ça devrait fonctionner.
Sinon si tu trouve ça trop lent tu peux incrémenter deux fois la variable X ou Y lorsque tu déplace ton bonhomme mais fait gaffes de ne pas dépasser les limites de l'écran.

3

Oui, j'ai oublié d'enlever le ret de la fin.
Tu crois que ce serait plus rapide avec les instructions conditionnelles de ion? (genre: bcallz() et autres)
On peut pas faire un truc qui soit vraiment plus rapide? Là, ce qui le rend aussi lent, c'est Ionfastcopy, Grbufclr, et le fait qu'il scanne le clavier?

(au fait, tes limites d'écran sont pas valables^^ tout du moins en haut...)

4

Normalement si, les limites commencent à 0, après c'est juste les limites normales : 96 et 64 moins la taille de la sprite : 16.

Sinon y'a pas grand chose à améliorer, le seul truc qui peux rendre lent ton programme ce sont les 'bcall' (mais pas les call comme ionFastCopy et toutes les routines d'Ion).

Sinon pour éffacer le graph buffer :

grbufclr:
	ld hl,plotSScreen
	ld de,plotSScreen+1
	ld (hl),%00000000
	ld bc,767
	ldir
	ret


Et t'appel ça avec un call : 'call grbufclr' .

5

Bon, je sais pas pour les limites, mais ça plante en haut.
Ca a l'air ingénieux l'instruction ldir (je viens de regarder sa fonction...). Tu crois que c'est plus rapide que bcall(_grbufclr)?
Sinon (c'est ce que j'avais fait au début), il suffit de faire call put 2 fois: la première pour effacer la sprite, et la deuxième pour la déplacer...
Bon, je vais essayer de coder pour que ça marche quand on appuie sur 2 touches.

Par contre, faut que tu m'expliques un truc: quand tu dis dans la source d'utiliser l plutot que hl; c'est pas possible que h contienne un autre valeur que 0 au début du prog? Et puis, c'est plus rapide? ça prend pas plus de place?

6

Je pense (mais je peux me tromper) que c'est plus rapide avec la routine 'ldir'.

Pour 'l' plutot que 'hl' c'est parce que la routine d'Ion n'utilise que 'l' mais après tu fait comme tu veux, c'est juste que je trouve que ça fait plus propre dans le code.

Après pour ce qui est du 'h' je croit que c'est au shell de remettre les registres à zéro et tout ça.

7

Pour les zones de Ram dispo j'ai vu que Ion propose SafeRam1, 2 et 3.
Il y'a a aussi le appsbackupscreen, le plotsscreen, le graph buffer...

C'est quoi les équivalences là dedans? Et quelle taille font ces zones (les screens font 768 octets, mais les autres???)

8

Le PlotSScreen et le Graph Buffer c'est pareil, et tu ne devrais pas stocker quelque chose dedans car c'est la mémoire graphique, tout ce qui est contenu là dedans sera copié à l'écran (avec ionFastCopy/etc...). Après l'appBackUpScreen c'est une zone mémoire qui fait aussi 768 bytes qui peut, par éxemple, stocker une copie du graph buffer.

Sinon les Saferam sont juste des zones de mémoire que l'on peut pratiquement utiliser sans danger. Elles sont définits dans ion.inc :
; saferam1 = 768 bytes (apdram)
; saferam2 = 531 bytes (statram)
; saferam3 = 128 bytes (textmem)
; saferam4 = 66 bytes (ops) ; saferam5 = 10 bytes (imathptrs)


Puis pour les autres zones : WikiTI.

9

Et à quoi sert call ionfastcopy? (je viens de voir qu'il existait déjà bcall grbufcopy...)
Pour l'équivalent de bcall grbufclr, j'ai testé, et en gros c'est la même vitesse que le bcall...

10

ionFastCopy ça sert à copier bien plus rapidement le graph buffer à l'écran (puis tant qu'a programmer avec Ion autant utiliser ses routines). Après tu verras que la plupart du temps il faut éviter de faire appel au bcall (ils ralentissent beaucoup les programmes).

11

ionFastCopy est carrément plus rapide que bcall grbufcopy, on sent la différence dans un programme qui met souvent à jour l'écran.

12

Y'a un moyen d'afficher un texte dans le graph buffer?
De tester si un pxl est allumé, et pas si le graph buffer dit qu'il l'est?

Et pourquoi ce code n'est pas valable? :

Header.
ld hl,1000

loop:
Instructions...
dec hl
jr nz,loop

Instructions après le loop
ret

En fait, ce code est assez aléatoire quand je le tape: parfois, je crois qu'il va jusqu'à 1000; mais souvent, il s'arrette avant...

13

T'as pas comparer 'hl' avec 0, à mon avis c'est pour ça. Mais sinon tu peux faire une boucle avec 'djnz', ça permet de décrementer tout seul le registre 'b' jusqu'à arriver à 0. Exemple :

ld b,255
Loop:
[ce que tu veux]
djnz Loop
[et la suite du programme]


Seulement le problème c'est que je croit que 'b' ne peut contenir qu'au max 255...
De tester si un pxl est allumé, et pas si le graph buffer dit qu'il l'est?


C'est bien plus simple avec le graph buffer, puisque c'est une représentation de l'écran dans la mémoire en binaire (0=pixel éteint et 1=pixel allumé).

14

Pour le loop jusqu'à 1000, je sais comment on fait, mais je pige pas pk là ça marche pas.
(on fait ld a,l puis or h...)
Y'a un moyen d'afficher un texte dans le graph buffer ou de tester si un pxl est allumé (pour les mêmes raisons...)?

15

Nan mais rajoute tu ne peux que comparer l'accumulateur (a) avec zéro, donc laisse tomber avec hl. Fait plusieurs boucles avec 'djnz Loop' où b peut contenir au max 255.

Et pour afficher du texte il faut que t'active un certain flag comme ça : 'set textwrite, (iy+sgrflags)' (au début de ton fichier). Puis après tout ce qui est affiché avec 'bcall(_vputs)' sera copié dans le graph buffer mais pas à l'écran (après avec 'ionFastCopy' tu peux afficher tout ça à l'écran). Puis sinon pour tester un pixel il faut que tu fasse ta propre routine, je croit qu'il n'y a pas de romcall pour ça.

16

Deeph, je te dis que ce code marche...
Essaye ce que je te dis:

ld hl,10000
loop:

Code...

ld a,l
or h
jr nz,loop

Et depuis, j'ai pigé pourquoi l'autre code marchait pas (en fait, contrairement à ce que dit asm in 28 days, dec Reg16bit ne met pas à jour le zero flag...)

Merci pour le code que tu m'as filé!

17

Ben c'est très normal que ca n'aie pas fonctionné, "dec hl" ne modifie aucun flag

18

Pour tester un pxl dans le buffer screen; il existe la routine de mirage (et puis c'est pas compliqué, c'est juste un pb d'adresses mémoires). Mais comment on accède à l'écran lui même???

19

J'en sais rien mais puisque le graph buffer représente l'écran, t'as juste à tester tes truc dedans (et puis en asm la plupart du temps tout ce que tu affiches passe d'abord par le graph buffer puis est copié à l'écran).

20

Pour accéder à l'écran, il faut passer par le driver qui est relié à certains ports du Z80. Regarde asmin28days, il doit y avoir une leçon.

21

Ah tiens je viens de me rendre compte qu'il y avait une routine 'ionGetPixel' avec Ion, c'est dans IonGuru.

22

Merci

23

je dis peu être des betise mais dans asm guru il y a une commande qui s'apelle ipoint ou _ipoint je sais plus et qui permet de changer la couleur d'un pixel, de la tester...

24

Yesss! Je l'utilise, mais je savais pas qu'on pouvait tester quoi que ce soit avec... Il faut rentrer quoi pour ça? (et y'a quoi en output?)

25

ASM GURU :
ROM CALL REFERENCE

_ipoint (4AE8h): Plots point on screen.

Input.
B, C are the x-y coordinates in pixels.
D is set either to 0 – light, 1 – dark, 2 – reverse, 3 – test pixel, 4 – copy from display buffer.

Output.
If D=3, Z is outputted as either 0 or 1 depending on whether the pixel is set or not.
All tutorials Copyright (c) James Matthews 1998, unless specified.


+ smile