1

Bonjour, j'ai déjà rédiger ce message sur un autre site alors je C/C:

Je me suis lancé il y a peu dans l'assembleur pour pouvoir programmer sur Ti-83. J'ai donc essayé de faire mon premier programme à partir de fragments de tutoriaux pêchés à droite et à gauche.

C'est une version ASM du programme en Ti-Basic de quelques lignes que j'ai sur ma calculatrice. Ultra-classique, il calcule le discriminant, le sommet, et la/les racines d'un trinôme à partir de ses trois coefficients. C'est un premier programme pour me faire la main, mais ça ne marche pas vraiment.
Voici mon code:

#include "input.asm"
#include "begin.asm"

;------------------------> variables
varstart = 8265h
;--------------------------------------------------
;variable name value size description
;--------------------------------------------------
var_a =varstart+9 ;9 coefficient en x² du trinôme
var_b =var_a+9 ;9 coefficient en x du trinôme
var_c =var_b+9 ;9 dernier terme en x^0 du trinôme
var_delta =var_c+9 ;9 discriminant (b²-4ac)
var_sommet =var_delta+9 ;9 var_sommet du trinôme (-b/2a)

call _clrLCDFull

call _homeup
call _zeroop1

call _newline
ld hl,debut
call _puts
call _newline

;obention de a

ld de,PROMPT
ld hl,prompta
ld bc,3

call PGMIO_EXEC

;transfert de OP1 vers var_a

ld hl,op1
ld de,var_a
ld bc,9
ldir

;obention de b

ld de,PROMPT
ld hl,promptb
ld bc,3

call PGMIO_EXEC

;transfert de OP1 vers var_b

ld hl,op1
ld de,var_b
ld bc,9
ldir

;obention de c

ld de,PROMPT
ld hl,promptc
ld bc,3

call PGMIO_EXEC

;transfert de OP1 vers _c

ld hl,op1
ld de,var_c
ld bc,9
ldir

;
;calcul du sommet (-b/2a)
;

;transfert de var_b vers OP1
ld hl,var_b
ld de,op1
ld bc,9
ldir

;inversion du signe
call changesign

;transfert de var_a vers op1 pour la multiplication par deux
;auparavant, sauvegarde de -b (op1) vers op2
call _OP1TOOp2
ld hl,var_a
ld de,op1
ld bc,9
ldir

call _TIMES2

;on remet -b dans op1, et 2a dans op 2 pour la division finale

call _OP1TOOP3 ;on met 2a dans op 3
call _OP2TOOP1 ;on met -b dans op 1
call _OP3TOOP2 ;enfin, on remet 2a dans op2, et on peut faire la division

call _FPDIV

;enfin, on sauvegarde le résultat dans var_sommet:
ld hl,op1
ld de,var_sommet
ld bc,9
ldir

;
;transfet de B vers OP1 puis calcul de b²
;

ld hl,var_b
ld de,op1
ld bc,9
ldir

call _FPSQUARE

;on retransfert b²(op1) dans op3 et on calcule maintenant 4ac

call _OP1TOOP3

call _op1set4
ld hl,op2
ld de,var_a
ld bc,9
ldir

;on effectue 4*A

call _FPMULT

;on charge maintenant C dans op2

ld hl,var_c
ld de,op2
ld bc,9
ldir

call _FPMULT

;enfin, on fait b²(op3) - 4ac(op1)

call _OP1TOOP2 ;on met 4ac dans op2 car c'est le deuxième terme
call _OP3TOOP1 ;on remet b² dans op1
call _FPSUB

;on a notre var_delta, on fait maintenant en fonction des valeurs
;sauvegarde de var_delta
ld hl,op1
ld de,var_delta
ld bc,9
ldir

call _op2set0
call _cpop1op2

jp m,deltaneg
jp z,delta0
jp p,deltapos

deltaneg:
ld hl,nosolution
call _puts

delta0:
;affichage de la chaîne puis du var_sommet
ld hl,solution
call _puts

ld hl,var_sommet
ld de,op1
ld bc,9
ldir

call _formDisp

deltapos:
;calcul des deux racines (-b-sqrt(var_delta)/2a)
;d'abord, on calcule racine de var_delta : on stocke var_delta dans op1
ld hl,var_delta
ld de,op1
ld bc,9
ldir

call _SQROOT
call _OP1TOOP2 ;on met sqrt(var_delta) dans op2
call _OP1TOOP6 ;on garde également en mémoire la valeur pour les futurs calculs

;on place var_b dans op1
ld hl,var_b
ld de,op1
ld bc,9
ldir

;inversion du signe
call changesign

call _FPSUB ;on soustrait maintenant

;on stocke temporairement -b-sqrt(var_delta)[op1] dans op3 pour faire la multiplication 2*a
call _OP1TOOP3

;multiplication de a par deux
ld hl,var_a
ld de,op1
ld bc,9
ldir

call _TIMES2

call _OP1TOOP2
call _OP3TOOP1

call _FPDIV ;enfin après avoir retransférer les valeurs où il faut, on divise le tout

;on stocke la première racine dans op4
call _OP1TOOP4

;on réutilise la valeur de sqrt(var_delta) stockée dans op6
call _OP6TOOP2

;on place var_b dans op1
ld hl,var_b
ld de,op1
ld bc,9
ldir

;inversion du signe
call changesign

call _FPADD

;on stocke temporairement -b+sqrt(var_delta)[op1] dans op3 pour faire la multiplication 2*a
call _OP1TOOP3

;multiplication de a par deux
ld hl,var_a
ld de,op1
ld bc,9
ldir

call _TIMES2

call _OP1TOOP2
call _OP3TOOP1

call _FPDIV ;enfin après avoir retransférer les valeurs où il faut, on divise le tout

;on stocke la deuxième racine dans op5
call _OP1TOOP5

;on affiche ensuite les valeurs

ld hl,solutions
call _puts

call _OP4TOOP1
call _formDisp
call _OP5TOOP1
call _formDisp

changesign:
ld a,(op1)
cp 0
call nz,set_pos
call z,set_neg
ret

set_pos:
ld a,0
ld (op1),a
ret

set_neg:
ld a,$80
ld (op1),a
ret

debut:
.db "Calcul du discriminant",0
prompta:
.db "A:",0
promptb:
.db "B:",0
promptc:
.db "C:",0
nosolution:
.db "Pas de solutions",0
solution:
.db "Une solution:",0
solutions:
.db "Deux solutions:",0

.end
END


Quand je l'exécute sur VTI, j'ai juste une ligne verticale de pixel qui s'affiche à droite et ça plante. Avant, j'utilisais des variables comme promptb (déclarées dans le segmet data, comme .db etc...) à la place de var_a, var_b, etc... mais ça ne marchait pas mieux, les invite prompt ne s'affichaient pas, je rentrais quand même trois nombre et ça me mettait enfin "Error : Division by zero".

J'aimerai donc que vous me donniez des conseils déjà pour que mon programme fonctionne, et ensuite si possible sur les utilisations de tel et tel routine, sur la déclaration, les techniques couramment utilisées, sur le style, etc...
bref toute suggestion qui me serait utile.
Merci d'avance, @++

2

Bon déjà l'Assembleur c'est pas ce qu'il y a de mieu pour faire des programmes de calcul (le TI-Basic convient mieu pour ce genre de programmes)...

Ensuite tu ferai mieu de télécharger un compilo 'normal' parce que je pense que pour compiler ça il faut y'aller cheeky : l'header n'est même pas correct. Essaye 'le mien' si tu veux : . Pour compiler avec il faut lancer le programme 'Compiler.bat' et taper 'asm le_nom_de_ta_source' avec, bien sur, aucuns espace dans le nom (et il faut qu'il ne soit pas trop grand) et sans spécifier l'éxtention (bien qu'il faut que ta source soit au format '.z80' ou '.asm').

Donc tu peux déjà remplacer le début de ta source par :

.nolist
#include	"ion.inc"			; On programme sous le shell Ion

;-------------------------------------------------------------
;Pour tes variables on utilise Saferam1 (cf la doc d'Ion)
;-------------------------------------------------------------
#define		var_a		Saferam1	;9 coefficient en x² du trinôme 
#define		var_b		Saferam1+1	;9 coefficient en x du trinôme 
#define		var_c		Saferam1+2	;9 dernier terme en x^0 du trinôme 
#define		var_delta	Saferam1+3	;9 discriminant (b²-4ac) 
#define		var_sommet	Saferam1+4	;9 var_sommet du trinôme (-b/2a)

.list
#ifdef TI83P
	.org ProgStart-2
	.db $bb,$6d
#else 
	.org ProgStart
#endif

	ret
	jr nc,Start
.db "Le nom de ton programme",0		; il apparaitra sous Ion

Start:


Ensuite, maintenant qu'on programme sous Ion il faut modifier une chose : les 'call _clrLCDFull' doivent être transformer en 'bcall(_clrLCDFull)' seulement s'il s'agit de rom calls, si ce sont des routines alors il faut continuer de les appelés avec 'call'.

Et puis j'ai pas vraiment regarder ton code source mais le reste me semble correct.

3

Bon déjà l'Assembleur c'est pas ce qu'il y a de mieu pour faire des programmes de calcul

Ok je retiens, mais bon c'était plus pour me faire la main que pour faire un programme vraiment utile...
l'header n'est même pas correct

J'ai oubliés de préciser, j'ai fait des petits header pour aller plus vite, ils sont très pauvres : begin.asm inclue tokens.inc, ti83asm.inc, et comporte l'instruction
.org 9327h
input.asm définit quelques romcall (PGMIO_EXEC) et valeurs (PROMPT) qui ne sont pas définies dans ti83asm.
J'utilise le compilateur tasm.

Sinon, mes variables a,b,c,delta,sommet doivent pouvoir contenir les valeurs des OP, il faut que je mette Saferam1+9, Saferam1+18, etc... nan ?
jr nc,Start : quelle est la différence avec jr Start ?

Merci de la réponse
@++

4

jr nc,Start : quelle est la différence avec jr Start ?


Bah ça ne lance le programme que si le carry flag n'est pas mis.
Sinon, mes variables a,b,c,delta,sommet doivent pouvoir contenir les valeurs des OP, il faut que je mette Saferam1+9, Saferam1+18, etc... nan ?


Je ne pense pas, suffit de faire 'Saferam1+1', 'Saferam1+2' etc...

Sinon c'est toujours plus simple de faire avec l'header d'Ion (et il n'est pas nécessaire de le comprendre), parce que le shell Ion porte automatiquement ton programme pour la TI 83 et la TI 83+ (mais ça nécessite de lancer ton programme avec Ion oncalc).