Page 3 sur 4

Re: Aide pour débutant en assembleur svp

Message non luPosté: 10 Sep 2019, 18:56
de Limonadd
Y'a un truc que tu devrais savoir michel.

Tu es en ADL=1 donc tes registres font 24 bits.

si tu fais par exemple:

ld hl, (adresse) (adresse est la valeur d'une adresse peut importe laquelle)

ou

ld (adresse), hl

qu'est ce qui se passe?

sur les ti c'est en "little endian" ce qui veut dire que quand tu stockes une valeur à une adresse, c'est les octets de poids plus faibles stockés en premier.

donc si tu fais:

ld (adresse),hl

tu as les 8 bits dans l stockés à "adresse", les 8 bits de h stockés à "adresse+1", et les 8 bits de hlu stockés à "adresse+2".

pareil en sens inverse.

ld hl, (adresse)

la valeur dans à l'adresse "adresse" va dans l, celle dans "adresse+1" va dans h, et celle de "adresse+2" va dans hlu.

donc si tu veux stockés seulement une valeur 8 bits à une adresse, tu la mets par exemple dans l, et ensuite tu la stockes:

ld l, 7
ld (adresse),l

là on a seulement modifié la valeur à cette adresse.

donc dans ton code quand tu écris:

LD hl,0
LD (curRow), hl
LD (curCol), hl

tu peux le simplifier. déjà comment sont stockés les valeurs de curRow et curCol?

comme tu peux le voir dans le wiki:

http://wikiti.brandonw.net/index.php?ti ... By_Address

à l'adresse $D00595 il y a curRow, à $D00596 curCol, et l'octet d'après est inutilisé.

donc si tu écris:

LD hl,0
LD (curRow), hl

tu mets un 0 dans curRow, dans curCol, et dans l'octet d'après :)

donc fait très attention, si par exemple tu veux simplement modifié la valeur de curRow et que tu fais par exemple,

ld hl,7
ld (curRow),hl

00000000-00000000-00000111
hlu--------------h-----------l-----

et donc tu mets un 7 dans curRow et 0 dans curCol

si tu veux simplement mettre un 7 dans curRow sans toucher à curCol tu fais:

ld l,7
ld (curRow),l

j'espère que j'ai été assez clair :)

Re: Aide pour débutant en assembleur svp

Message non luPosté: 10 Sep 2019, 19:27
de emilechombier
:o aAAAAh.... merci de tes longues explications, c'est très sympa mais hélas
ld l,7
ld (curRow),l
SPASM m'affiche : "error SE110: The opcode LD was given invalid operands" :bang:
Apparemment il faut absolument que je mette hl pour (curRow)

edit: ça marche en utilsant le registre "a" :comprends_po:

Re: Aide pour débutant en assembleur svp

Message non luPosté: 11 Sep 2019, 11:19
de Limonadd
Oui pardon dsl j'étais fatigué xD

tu peux envoyer une valeur 8 bits directement dans une adresse seulement avec a

tu peux le faire indirectement en mettant ton adresse dans hl par exmple

donc soit tu utilises a, soit a est occupé et donc par exemple tu peux mettre ton adresse dans hl

ld e,7
ld hl,curRow
ld (hl),e

ou

ld hl,curRow
ld (hl),7

ou avec a

ld a,7
ld (curRow),a

mais si tu utilises hl

ld hl,0
ld (curRow),hl

n'oublies pas que tu modifies aussi curCol

donc si tu veux mettre 7 dans curRow et 5 dans curCol tu peux faire:

ld h,5
ld l,7
ld (curRow),hl

petite précision
tu peux faire ça avec hl:

ld (hl),7

mais avec un autre registre tu dois passer par a

ld a,7
ld (bc),a
ld (de),a

et pareil dans l'autre sens

voilà :) donc encore toutes mes excuses pour l'erreur je faisais plus trop attention à ce que j'écrivais XD

Re: Aide pour débutant en assembleur svp

Message non luPosté: 11 Sep 2019, 14:03
de emilechombier
merci merci,
oui maintenant avec l'habitude, pour mettre le curseur en ligne 8 et colonne 3 je fais:
Code: Tout sélectionner
ld hl,$0308
ld (curRow), hl

en hexa c'est plus lisible et plus compact (mais effectivement un non-initié ne voit pas que ça modifie le numéro de colonne )

Re: Aide pour débutant en assembleur svp

Message non luPosté: 24 Sep 2019, 20:39
de emilechombier
Petit retour pour donner des nouvelles:

emilechombier a écrit:Bonjour,
Voilà j'ai programmé ma double boucle de 100 itérations en ASM.
C : 1,3 secondes
ASM : 50 secondes !


C'était bien le call _DispHL car après des heures d'apprentissages/essais/erreurs laborieux je commence à comprendre l'assembleur du eZ80 et j'ai réussi à faire une routine d'affichage de nombre : je divise par 10 (en faisant une succession de soustractions par 10), j'affiche le chiffre du reste, et je recommence avec le quotient pour les dizaines, etc.

Je passe de 50 secondes en ASM avec _DispHL à 17 secondes avec ma routine. Je n'ai toujours pas réussi à retrouver les 1,3 secondes du programme en C (!) mais je suis assez content!
Autre souci: ça bug au-dessus de 650000 environ, ma routine est de toutes façons un peu trop longue pour les grands nombres.
Je vous partage quand mêm le bout de code:
Code: Tout sélectionner
;Affiche 500000  en bout de 4ème ligne
#include "ti83pce.inc"
   .assume ADL=1
   .db tExtTok,tAsm84CeCmp
   .org userMem
    call _ClrScrnFull
    call _homeup
    ld hl, 500000
    ld de, 3
    ld (curRow), de
    ld de, 10
    ld ix, 25
    scf
    ccf
Debut:
    ld bc, 0
Soustraction:
    inc bc
    sbc hl, de
    jr NC, Soustraction
    add hl, de
    ld a, l
    add a, $30
    ld (curCol), ix
    call _PutMap
    dec ix
    dec c
    ld hl,0
    ld l, c
    ld h, b
    ld a, l
    cp a, 0
    jr NZ, Debut
    ld (curCol), ix
    ld a, $D6
    call _PutMap
    res donePrgm,(iy+doneFlags)
    RET

Re: Aide pour débutant en assembleur svp

Message non luPosté: 25 Sep 2019, 15:07
de Limonadd
Je pense que le bug vient du fait que tu ne copies que b et c dans h et l et pas la partie supérieur de bc dans celle de hl.
J'ai repris ton code que j'ai modifié, on peut du coup afficher de 0 jusqu'a $FFFFFF, le seul problème c'est que la routine devient très lente pour les gros nombres, et j'ai jamais été doué en optimisation, mais peut être que toi tu as une idée pour le rendre plus rapide :)

première chose à corriger:
copier tout BC dans HL

deuxième chose à corriger:
à la fin tu teste seulement si l n'est pas égal à 0, tu dois tester si TOUT HL n'est pas égal à 0
ton code marche avec plein de nombre, mais si par exemple tu prends le nombre: $A00000 (=10485760)
si tu testes seulement l ça t'afficheras 0 car il y a bien 0 dans l. Tu dois donc tester tout hl :)

Code: Tout sélectionner
#include "ti83pce.inc"

   .assume ADL=1
   .db $EF,$7B
   .org userMem

  call _ClrScrnFull

  ld hl, 756580
  ld de,$001903
  ld (curRow),de

  ld de,10
  ld ix,25
  ld bc,0

  jr _sub

__:
  pop de
  pop hl
_sub:
  inc bc
  or a
  sbc hl,de
  jr nc,_sub
  add hl,de

  ld a,l
  add a,$30
  call _PutMap
  dec ix
  ld (curCol),ix
 
  dec bc
  push bc
  pop hl
  ld bc,0

  push hl
  push de
 
  ld de,1
  or a
  sbc hl,de
  jp nc,__

  pop de
  pop hl

  ret

Re: Aide pour débutant en assembleur svp

Message non luPosté: 25 Sep 2019, 17:24
de Limonadd
si on remplace les soustractions par une division par 10 directement, ça devrait être plus rapide pour les gros nombres

Re: Aide pour débutant en assembleur svp

Message non luPosté: 25 Sep 2019, 17:55
de emilechombier
justement j'ai fait comme ça car je n'ai pas vu d'instruction de division simples dans le manuel de l'eZ80 ni dans les System Routines, sauf sur des complexes ou en virgule flottante... (bon ça date de 2002, il y a peut-etre eu des progrès depuis...)

Sinon j'ai pensé à faire des boucles de soustractions par 100000, puis par 10000, puis par 1000 etc. c'est plus long à écrire (mais ce serait peut-être plus rapide pour les grands nombres).

Re: Aide pour débutant en assembleur svp

Message non luPosté: 25 Sep 2019, 18:10
de Limonadd
d'ailleurs comment tu fais pour voir en cb de temps est éxécuté un code?
(et tu comprends le code en haut avec les push/pop ? ou tu veux que le commente?)

Re: Aide pour débutant en assembleur svp

Message non luPosté: 25 Sep 2019, 18:36
de Limonadd
j'ai refait un code en divisant par 10 et même l'affichage du plus grand nombre possible est rapide! ($FFFFFF)
pour faire la division je me suis basé sur le tuto jour 15

Code: Tout sélectionner
;__________________________________
#include "ti83pce.inc"

   .assume ADL=1
   .db $EF,$7B
   .org userMem

  call   _ClrScrnFull

  ld     hl, $FFFFFF
  ld     de,$001903
  ld     (curRow),de

  ld     ix,25
 
  jr     __
_loop:
  pop    hl
__:
  call   _DivHLby10
  add    a, $30
  call   _PutMap

  dec    ix
  ld     (curCol),ix

  push   hl

  ld     de,1
  or     a
  sbc    hl,de
  jp     nc, _loop

  pop    hl

  ret

_DivHLby10:
;divide hl (24 bits) by 10
;destroys e and b
;  INPUT:
;--_--_--_--_--|: hl : dividend
;  OUTPUT:
;--_--_--_--_--|: hl : result
;--_--_--_--_--|:  a : remainder
  xor    a
  ld     e,10
  ld     b,24
_lp:
  add    hl,hl
  rla
  cp     e
  jr     c,_skp
  sub    e
  inc    l
_skp:
  djnz   _lp

  ret