Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur l'Assembleur !

Modérateur : mazertoc

appel aux specialistes ASM decalage 96 bits
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#1 Message par paulfjujo » sam. 25 mai 2019 10:24

bonjour à tous,

Ce n'est pas (encore) l'appel du 18 juin !
mais j'en appelle aux specialistes de l'ASM , pour un simple décalage de bit sur un mot de 96 bits..

pour realiser le defilement de texte , pixel by pixel sur un ensemble de 3 Matrices de 4 modules MAX7219 leds 8x8
ce qui represente un texte de 3x4x8 =96 bits de large ( matrice car 8x8) et donc 96 bytes .
ces 96 bytes organisés par 3 long de 32 bits consécutifs..

pour etre sur qu'ils le soient placés par le compilateur , et à une adresse connue , donc accessible en ASM par le compilateur en C.
usage de absolute adresse

Code : Tout sélectionner


static signed long L10  absolute 0x40
;
static signed long L11  absolute 0x44;
static signed long L12  absolute 0x48;
static char Bn[12] absolute 0x040;
char * P_Byte


le langage C permet le decalage de bit , mais ne se souscie pas du report Carry bit ..
sous la forme langage C , voilà comment j'opere pour decaler 96 bits à gauche ..
mais c'est quand meme TRES LOURD.

Code : Tout sélectionner



 
// --- test zone ----
  // init de l' ensemble pour megamot  de 96 bits
  L10=0x40555453;  //LSB
  L11=0xFFAAFF20;  //MSB
  L12=0x0102FF80; //HSB
   for (i=0;i<12;i++)
   {
     Decompile_byte(Bn[i],0) ;CRLF1();
    }
    CRLF1(); CRLF1();
   Delay_ms(3000);
   P_Byte=0x000040;
   for (i=0;i<12;i++)
    {
     ByteToHex(*(P_Byte+i),CRam1);
     UART1_Write_Text(CRam1);
     CRLF1();
     }
      Delay_ms(3000);
     CRLF1(); CRLF1();
     
    
// decalage de 1 bit de l'ensemble 
    // visu AVANT
    Binarise_32bits(L12,CRam1); UART1_Write_Text(CRam1);UART1_Write('-');
    Binarise_32bits(L11,CRam1); UART1_Write_Text(CRam1);UART1_Write('-');
    Binarise_32bits(L10,CRam1); UART1_Write_Text(CRam1);;CRLF1();
    CRLF1();
     
       
//hypothese de depart carry=0
       c1=0;
       L10=L10<<1;
       L10=L10 +c1;
       if ((L10 & 0x8000) == 0x8000) c1=1; else c1=0;
       L11=L11<<1;
       L11=L11 +c1;
       if ((L11 & 0x8000) == 0x8000) c1=1; else c1=0;
       L12=L12<<1;
       L12=L12 +c1;
  // visu APRES 
    Binarise_32bits(L12,CRam1); UART1_Write_Text(CRam1);UART1_Write('-');
    Binarise_32bits(L11,CRam1); UART1_Write_Text(CRam1);UART1_Write('-');
    Binarise_32bits(L10,CRam1); UART1_Write_Text(CRam1);;CRLF1();
    CRLF1();
 


je pense qu'une solution 100%ASM serait beaucoup plus concise et rapide ..
:mur: mais c'est maintenant trop loin pour moi..


idea ! Si un de vous peut se pencher sur mon probleme ?

je joins ici le projet MikroC complet, affichage fixe OK sur 12 matrices , mais defilement stopé sur ce probleme de decalage bit.

Test_12_Matrices8x8_18F26K22_190525.zip


affichage terminal:
Capture_test_96bits.jpg
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

appel aux specialistes ASM decalage 96 bits
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » sam. 25 mai 2019 16:16

Bonjour Paul et à tous,

je suis pas très spécialiste des allers-retours entre C et asm, c'est soit l'un soit l'autre.
L'asm a effectivement l'avantage d'avoir l'instruction "rotate" que n'a pas le C.
Après quelques recherches voilà ce que cela donne en C18.

On définit un tableau de 3 long qui sont stockés par C18 en format little endian, c'est à dire dans cet ordre :
- octet de poids faible de u[0]
- ...
- octet de poids fort de u[0]
- octet de poids faible de u[1]
- ...
- octet de poids fort de u[1]
- octet de poids faible de u[2]
- ...
- octet de poids fort de u[2]

D'après ce que j'ai constaté, C18 met les variables en adresse haute, au dessus de 0xF80, pour pouvoir les adresser rapidement en mode ACCES, sans spécifier de bank.
En utilisant movlb, on spécifie la bank avant d'accéder à la variable, c'est plus sûr.
La variable doit être globale, en locale ça se complique ....

Code : Tout sélectionner

unsigned long u[3];

void main(void)
{
  int i;
  u[0] = 1; u[1] = 0; u[2] = 0;   // variable 96 bits contient 1

  _asm
  bcf   STATUS,0,0        // clear bit c (bcf STATUS,0,ACCESS)
  movlb u                 // sélection bank contenant u
  _endasm

  for (i=0; i<95; i++) {
    _asm
    rlcf  u+0,1,1         // rotate left through carry de u[0] (rlcf u,F,BANKED)
    rlcf  u+1,1,1
    rlcf  u+2,1,1
    rlcf  u+3,1,1

    rlcf  u+4,1,1         // rotate left through carry de u[1]
    rlcf  u+5,1,1
    rlcf  u+6,1,1
    rlcf  u+7,1,1

    rlcf  u+8,1,1         // rotate left through carry de u[2]
    rlcf  u+9,1,1
    rlcf  u+10,1,1
    rlcf  u+11,1,1
    _endasm
  }
}


En partant de u = 1, c'est a dire :
u[0] = 0x00000001
u[1] = 0x00000000
u[2] = 0x00000000

après 95 rotations, on obtient bien
u[0] = 0x00000000
u[1] = 0x00000000
u[2] = 0x80000000

Il faudrait peut être sauvegarder le registre BSR sélecteur de bank, avant de faire le movlb, pour le restituer ensuite.
Le listing désassemblé devrait indiquer si le C se rétablit bien, dans le cas où on omet cette sauvegarde.

Reste à voir avec MikroC, je vais regarder, mais je suis pas à l'aise avec.

appel aux specialistes ASM decalage 96 bits
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#3 Message par JJE » sam. 25 mai 2019 19:02

Bonsoir paulfjujo et satinas,

satinas a écrit :Source du message   _asm
  bcf   STATUS,0,0        // clear bit c (bcf STATUS,0,ACCESS)
  movlb u                 // sélection bank contenant u
  _endasm

  for (i=0; i<95; i++) {
    _asm
rlcf u+0,1,1 // rotate left through carry de u[0] (rlcf u,F,BANKED)
rlcf u+1,1,1
rlcf u+2,1,1
rlcf u+3,1,1

rlcf u+4,1,1 // rotate left through carry de u[1]
rlcf u+5,1,1
rlcf u+6,1,1
rlcf u+7,1,1

rlcf u+8,1,1 // rotate left through carry de u[2]
rlcf u+9,1,1
rlcf u+10,1,1
rlcf u+11,1,1
_endasm

est-on sûr que le for (i=0; i<95; i++), compilé, ne touche pas à STATUS,C ?
La variable i étant déclarée en C de manière à être accessible en asm (un char suffit), pourquoi ne pas écrire un truc du genre

Code : Tout sélectionner


 _asm
  movlb u
  movlw    .95
  movwf    i
  bcf   STATUS
,0,0        // clear bit c (bcf STATUS,0,ACCESS)
bcl
    movf        i
,f
    btfsc        STATUS
,Z
    goto    finbcl
    rlcf  u
+0,1,1         // rotate left through carry de u[0] (rlcf u,F,BANKED)
    rlcf  u+1,1,1
    rlcf  u
+2,1,1
    rlcf  u
+3,1,1

    rlcf  u
+4,1,1         // rotate left through carry de u[1]
    rlcf  u+5,1,1
    rlcf  u
+6,1,1
    rlcf  u
+7,1,1

    rlcf  u
+8,1,1         // rotate left through carry de u[2]
    rlcf  u+9,1,1
    rlcf  u
+10,1,1
    rlcf  u
+11,1,1
    decf    i
, f
    goto bcl
finbcl    
    _endasm
      

qui fait tout le travail en asm ?
La remarque sur BSR reste valide

PS : je n'ai jamais touché à C sur PIC :sifflotte:
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e

appel aux specialistes ASM decalage 96 bits
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#4 Message par paulfjujo » sam. 25 mai 2019 19:12

bonsoir,


merçi à vous deux,
je m'en vais tester celà...
Aide toi, le ciel ou FantasPic t'aidera

appel aux specialistes ASM decalage 96 bits
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#5 Message par satinas » sam. 25 mai 2019 19:26

Bonjour JJE,

La boucle de 95 itérations fait partie de mon exemple, c'est pourquoi je l'avais laissée en C.
Tu as tout a fait raison, pour le clear carry, il est mal placé, il faut le mettre juste avant le premier rlcf.
Le movlb doit aussi être déplacé pour la même raison, la boucle for peut modifier BSR.

appel aux specialistes ASM decalage 96 bits
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#6 Message par JJE » dim. 26 mai 2019 02:10

Bonsoir ou bonjour satinas,
satinas a écrit :Source du message Tu as tout a fait raison, pour le clear carry, il est mal placé, il faut le mettre juste avant le premier rlcf.

Je ne sais pas exactement ce que veut faire paulfjujo, si c'est un décalage logique je suis d'accord avec toi, si c'est un rotate, je ne suis pas d'accord, et dans ce cas, je ne vois pas comment on peut laisser la boucle en C, d'ailleurs, est-ce fâcheux de la coder aussi en assembleur ?
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e

appel aux specialistes ASM decalage 96 bits
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#7 Message par satinas » dim. 26 mai 2019 06:57

Bonjour JJE

Voilà comment je vois les choses.
Le C fait un shift simple, il fait entrer un 0 dans le bit de poids faible, et fait sortir le bit de poids fort.
En suite, il y a le shift/rotate avec/through carry, la carry fournit le bit entrant, et récupère le bit sortant.
Et en dernier le rotate sans/without carry, ou la carry n'intervient pas, le mot tourne sur lui-même.

Paul veut un shift avec carry, qui s'appelle rotate through carry dans l'asm du pic.
le 16F fait le rotate avec carry gauche/droite RLF et RRF
le 18F fait les 2 rotates, avec carry RLCF RRCF, et sans carry RLNCF RRNCF

Si l'on veut une rotation complète des 96 bits, il manque le bit entrant de poids faible.

Code : Tout sélectionner

    movlb u               // sélectionner bank, renseigner BSR
    rlcf  u+11,1,1        // placer dans  carry le bit haut b95 qui va entrer à droite en b0, u[2] décalé d'1 bit
    rrncf u+11,1,1        // redécaler u[2] vers la droite, sans toucher à la carry

    rlcf  u+0,1,1         // rotate left through carry de u[0] (rlcf u,F,BANKED)
    rlcf  u+1,1,1
    rlcf  u+2,1,1
    rlcf  u+3,1,1

    rlcf  u+4,1,1         // rotate left through carry de u[1]
    rlcf  u+5,1,1
    rlcf  u+6,1,1
    rlcf  u+7,1,1

    rlcf  u+8,1,1         // rotate left through carry de u[2]
    rlcf  u+9,1,1
    rlcf  u+10,1,1
    rlcf  u+11,1,1


Quant à choisir ce qui doit être fait en ASM ou en C, pour ma part, étant un grand indécis, je fais les deux :)
Ta boucle en ASM est optimisée, elle est bien sûr à préférer à un compilateur sans optimisation.
Il faut dans ce cas vérifier que i et u sont dans la même bank, sinon il faut jouer avec BSR. Ou alors utiliser WREG comme indice de boucle, et l'adresser en mode access.

Paul, tu veux un décalage avec 0 entrant comme dans ton programme, ou une rotation complète des 96 bits ?

appel aux specialistes ASM decalage 96 bits
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#8 Message par paulfjujo » dim. 26 mai 2019 11:14

bonjour à tous ,

satinas a écrit :Paul, tu veux un décalage avec 0 entrant comme dans ton programme, ou une rotation complète des 96 bits ?


Pour moi, la version ASM est le moyen le plus efficace d'optimiser la vitesse d'execution
pour ne pas voir un defilement laterale saccadé ou en diagonale !
mon but est de decaler un message de 96 bytes, pixel par pixel de la droite vers la gauche
appelons BIGMOT ce registre de 96 bits constitués de 3 long (32 bits)
donc au total j'aurai 8 BIGMOT de 96 bytes ..

dans un premier temps je veux tester 1 seul BIGMOT
pour le message defilant , avant de remplir mes 12 caracteres (vides) , le carry sera à zero
et seulement apres le 1er tour de piste ( puisque le message defile en boucle)
le 1er carry bit sera le dernier MSB bit du dernier pixel affiché à l'extreme gauche de l'affichage
puisqu'il faudra recopier le pixel sortant à gauche , vers l'entree à droite du registre BIGMOT.

BIGMOT est un registre à decalage circulaire
le dernier bit réetrant dans le 1ER APRES le 1er tour de piste .

avec la directive absolute,
les 3 entiers long restent dans la page zero 0x0040 0x0044 0x0048
de meme que le compteur de boucle cnt en 0x0038
Aide toi, le ciel ou FantasPic t'aidera

appel aux specialistes ASM decalage 96 bits
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#9 Message par paulfjujo » dim. 26 mai 2019 11:22

paulfjujo a écrit :bonjour à tous ,

satinas a écrit :Paul, tu veux un décalage avec 0 entrant comme dans ton programme, ou une rotation complète des 96 bits ?


Pour moi, la version ASM est le moyen le plus efficace d'optimiser la vitesse d'execution
pour ne pas voir un defilement laterale saccadé ou en diagonale !
mon but est de decaler un message de 96 bytes, pixel par pixel de la droite vers la gauche
appelons BIGMOT ce registre de 96 bits constitués de 3 long (32 bits)
donc au total j'aurai 8 BIGMOT de 96 bytes ..

dans un premier temps je veux tester 1 seul BIGMOT
pour le message defilant , avant de remplir mes 12 caracteres (vides) , le carry sera à zero
et seulement apres le 1er tour de piste ( puisque le message defile en boucle)
le 1er carry bit sera le dernier MSB bit du dernier pixel affiché à l'extreme gauche de l'affichage
puisqu'il faudra recopier le pixel sortant à gauche , vers l'entree à droite du registre BIGMOT.

BIGMOT est un registre à decalage circulaire
le dernier bit réetrant dans le 1ER APRES le 1er tour de piste .

avec la directive absolute,
les 3 entiers long restent dans la page zero 0x0040 0x0044 0x0048
de meme que le compteur de boucle cnt en 0x0038


Variables_at_Aboslute_adressse.jpg



mes premiers tests ne sont pas concluant:

BIGMOT initialisé à 1
pour voir ce bit se deplacer , Cnt limité à 90 ..
et pour etre sur que le carry ne tombe pas en dehors de BIGMOT



Code : Tout sélectionner

//init
char cnt absolute 0x38;
char Depart absolute 0x040;
long L10  absolute 0x40;
long L11  absolute 0x44;
long L12  absolute 0x48;


     Depart=0;
       L10=1;
        L11=0;
        L12=0;

        UART1_Write_CText("\r\nAvant decalage \r\n");
        Binarise_32bits(L12,CRam1,1);
        UART1_Write_Text(CRam1); UART1_Write('-');
        // CRLF1();
        Binarise_32bits(L11,CRam1,1);
        UART1_Write_Text(CRam1);  UART1_Write('-');
        // CRLF1();
        Binarise_32bits(L10,CRam1,1);
        UART1_Write_Text(CRam1);
        CRLF1();

        cnt=0;
        _asm {
        movlb _Depart
        movlw    90
        movwf _cnt
        bcf   STATUS
,0,0        // clear bit c (bcf STATUS,0,ACCESS)
  bcl:
        movf    _cnt,F
        btfsc        STATUS
,Z
        goto    finbcl
        rlcf  _Depart
+0,1,1         // rotate left through carry de u[0] (rlcf u,F,BANKED)
        rlcf  _Depart+1,1,1
        rlcf  _Depart
+2,1,1
        rlcf  _Depart
+3,1,1

        rlcf  _Depart
+4,1,1         // rotate left through carry de u[1]
        rlcf  _Depart+5,1,1
        rlcf  _Depart
+6,1,1
        rlcf  _Depart
+7,1,1

        rlcf  _Depart
+8,1,1         // rotate left through carry de u[2]
        rlcf  _Depart+9,1,1
        rlcf  _Depart
+10,1,1
        rlcf  _Depart
+11,1,1
        decf   _cnt
, F
        goto bcl
  finbcl
:
     }
      
        UART1_Write_CText
("\r\nApres 90 decalage \r\n");
        Binarise_32bits(L12,CRam1,1);
        UART1_Write_Text(CRam1); UART1_Write('-');
       // CRLF1();
       Binarise_32bits(L11,CRam1,1);
       UART1_Write_Text(CRam1);  UART1_Write('-');
       // CRLF1();
       Binarise_32bits(L10,CRam1,1);
       UART1_Write_Text(CRam1);
       CRLF1();
       



resultat

Avant decalage
00000000-00000000-00000000-00000000-00000000-00000000-00000000-00000000-00000000-00000000-00000000-00000001

Apres 90 decalage
10111111-11111111-11111111-11111111-11111111-11111111-11111111-11111111-11111111-11111111-11111111-11111111
... Waiting Keyboard Touch for <100 x 100mS >

humour!! un peu trop épicé (trop de carry)

une idée, ou wrong programm de ma part ?
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

appel aux specialistes ASM decalage 96 bits
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#10 Message par JJE » dim. 26 mai 2019 11:53

je ferais bien péter les 3 premières instructions de la boucle ET
remplacerais bien le decf _cnt, F de fin de boucle par descsz _cnt, F qui ne touche pas à STATUS
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e


Retourner vers « Langage ASM »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 44 invités