HectorDuino

Placez ici vos trucs et astuces, étalez sans retenue votre savoir-faire et votre science qui va nous permettre de redonner une apparence neuve et fonctionnelle à nos bouzes.

Modérateurs : Papy.G, fneck, Carl

__sam__
Messages : 5166
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ » 06 oct. 2015 22:23

Oui c'est étrange ce gif qui ne se crée pas. Je me demande si le script modifié pour ne pas passer par le flux standard de ffmpeg n'arrive simplement pas à retrouver la fin de fichier et partirait en boucle suite à ca.

Sinon pour la biche c'est parfait! rapide et tout. Cool 8) Il y en a plein d'autres ici: https://videos.pexels.com/tags/nature, comme par exemple - oh la vache!
Image

Pour le lag, oui c'est logique: il y a 2x plus de pixels à afficher qu'en BR. Mais du coup ca permet de réflechir aux optims. Coté ASM, je ne connais pas les cycles du Z80, mais je suppose que tu es déjà au taquet ?
Modifié en dernier par __sam__ le 06 oct. 2015 22:44, modifié 1 fois.
Samuel.
A500 Vampire V2+ ^8^, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.

Avatar du membre
yo_fr
Messages : 1329
Enregistré le : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr » 06 oct. 2015 22:37

Ben le player me semble pas mal dans l'état, mais la vrai voie de réduction des cycles est dans le principe d'échange où je vais essayer d'envoyer les octets à la queue leu leu sans les cycles nécessaires à la synchro avec les 7474.
comme je le disais c'est un gros boulot et je me donne 2 semaines pour rendre ça fonctionnel. 8)

(de plus il n'y a que le 1er script qui fonctionne bien. Les autres, ffmpeg ne génère pas les images, ce qui ne rime à rien car structure me semble identique dans les 3 cas [Le script d'origine (P6 du fil) le script tst_hrx.pl de ce matin et celui de ce soir])

__sam__
Messages : 5166
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ » 06 oct. 2015 23:08

En survolant le jeu d'instruction Z80, j'ai l'impression que les opcode push sont plutôt rapides car il permettent d'écrire 16 bits d'un coup en mémoire tout en updatant le pointeur.
Samuel.
A500 Vampire V2+ ^8^, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.

Avatar du membre
yo_fr
Messages : 1329
Enregistré le : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr » 07 oct. 2015 09:05

Le code permettant de recevoir un octet synchro est le suivant :

Code : Tout sélectionner

BCL_4:      
      IN      A,(PORTC)        ; lecture portC 
      AND     $10              ; PC4? Octet suivant D>H disponible ?
      JR      Z,BCL_4          ; attente
      LD      A,$05            ; X0/X2 => PC0 / PC2 à 1
      OUT     (PORTC),A        ; Validation octet envoyé sur PORTB
      IN      A,(PORTB)        ; Lecture PORTA (octet en provenance Disk)
      LD      H,A              ; octet reçu dans H       
      LD      A,$07            ; X0/X1/X2 => PC0 PC1 PC2   
      OUT     (PORTC),A        ;  RAZ du bit X1 => validation lecture
(selon l'utilisation de l'octet, le LD H,A peut se transforme en autre chose)

Donc hormis ce code de réception j'ai une boucle qui :
1) récupère l'octet d'offset
2) le test à 0 => saut à réception pour nouvelle @
3) addition HL et l'octet reçu (prog optimisé)
4) récupère un octet => LD (HL), octet reçu
5) INC HL
6) récupère un octet => LD (HL), octet reçu
7) INC HL
8 ) récupère un octet => LD (HL), octet reçu
9) INC HL
10) récupère un octet => LD (HL), octet reçu
11) reboucle en 1

réception pour nouvelle @:
20) récupère un octet => LD H, octet reçu
21) récupère un octet => LD L, octet reçu
22) Test si HL = 0 => fin de programme
23) récupère un octet => LD (HL), octet reçu
24) reboucle en 1

Voila comment fonctionne le player.

Mon but serait de faire :

1) récupère l'octet d'offset de façon synchronisée (comme avant)
2) récupération directe l'octet 2
3) récupération directe l'octet 3
4) récupération directe l'octet 4
5) le test à 0 de l'offset => saut à réception pour nouvelle @
6) addition HL et l'octet reçu (prog optimisé)
7) LD (HL), octet 2
8 ) INC HL
9) LD (HL), octet 3
10) INC HL
11) LD (HL), octet 4
12) INC HL
13) reboucle en 1

réception pour nouvelle @:
20) Avec l'octet 2=> LD H, octet 2 reçu
21) Avec l'octet 3=> LD L, octet 3 reçu
22) Test si HL = 0 => fin de programme
23) Avec l'octet 4 => LD (HL), octet 4 reçu
24) reboucle en 1

L'avantage de cette solution est de passer sans le code que j'ai donné en 1er et qui prend beaucoup de temps et qui se traduirait par seulement le IN A,(PORTB) ! L'inconvénient était de devoir synchroniser les temps d'expédition des octets depuis l'Arduino.

Le passage de LD (HL),A + INC HL à PUSH sera aussi à terme à voir (le pointeur d'adresse écran passant de HL à SP) c'est plus économique en cycle et en plus en sort 2 octets ! C'est une bonne idée aussi (auquel cas il faudra que je passe à 5 octets en synchro, qui n'est pas modulo 512 pour la lecture SD).

__sam__
Messages : 5166
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ » 07 oct. 2015 10:37

oui il faut économiser les cycles au maximum. Le passage de HL à SP devrait en faire gagner.. Mais il faudra remplir l'écran de bas en haut, mais la logique de décodage sera sensiblement la même.

Si on fait le compte de cycles, le code actuel prend combien de temps? (en supposant le Z80 à 4Mhz).
Samuel.
A500 Vampire V2+ ^8^, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.

Avatar du membre
yo_fr
Messages : 1329
Enregistré le : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr » 07 oct. 2015 11:13

j'ai pas calculé, mais la question est intéressante et j dois passer par là (le calcul des cycles).
PS : le Z80 est à 5 Mhz sur Hector :wink:

__sam__
Messages : 5166
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ » 07 oct. 2015 21:49

__sam__ a écrit :Mais quelques remarques:
  • Je vais refaire les vidéos...
Voilà: http://dl.free.fr/wuI5PBfRq
Samuel.
A500 Vampire V2+ ^8^, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.

Avatar du membre
yo_fr
Messages : 1329
Enregistré le : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr » 07 oct. 2015 22:32

Je vais en avoir pour des heures de visionnage de vidéo sur mon Hector !

à la fin j'aurais cette tête : :shock:

__sam__
Messages : 5166
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ » 08 oct. 2015 01:03

:D :roll:
Samuel.
A500 Vampire V2+ ^8^, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.

Avatar du membre
yo_fr
Messages : 1329
Enregistré le : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr » 08 oct. 2015 22:11

En fait ça été plus rapide que ce que je croyais :shock:
J'ai donc modifié l'encodeur et le player ainsi que le code Arduino pour faire presque ce que je disais : Envoi des octets en synchro temporelle.

Sachant que je travaille maintenant par paquet de 4 octets, j'expédie donc mes 4 octets comme ceci:
1 octet envoyé en synchro,
1 octet non synchronisé
1 octet envoyé en synchro,
1 octet non synchronisé

Ceci m'a fait passé de 30ko/sec à 50 ko/s !!!

Tout de suite une vidéo :



Pour info j'ai dû désactivé les interruptions (sinon j'ai des sauts d'images) et le calcul ne s'effectue plus en fin de vidéo.
La vidéo est encodée en "full speed", ce qui veux dire que je ne force pas des ralentissements si l'image n'est pas assez chargée. Évidement dans une version plus définitive cela sera re-ajouté !

Plus tard j'essayerais de passer avec 1 synchro et 3 octets en temporel. cela devrait me propulser aux alentours de 70 ko/s !!!

Là je suis content :wink: :D

__sam__
Messages : 5166
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: HectorDuino

Message par __sam__ » 09 oct. 2015 01:11

Whaou tu as quasiment doublé la bande passante et ca se voit :!: Le clip file à une vitesse d'enfer. Les Gifs sont à 10fps, là tu je pense qu'on peut monter à 15fps.

Par contre l'image a l'air "tassée". C'est normal ?
Samuel.
A500 Vampire V2+ ^8^, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.

Avatar du membre
yo_fr
Messages : 1329
Enregistré le : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr » 09 oct. 2015 08:59

C'est pour cela que je voulais absolument faire cette modification avant de réaliser des optimisations de cycle dans le code Z80. Je voulais doubler la bande passante et j'y suis presque :D .
Pour ce qui est de la résolution, Hector est en HR à 243 * 231 et 113*77 en BR. J'agrandirais les gifs après que si la bande passante le permet :wink: .

Avatar du membre
6502man
Messages : 10098
Enregistré le : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: HectorDuino

Message par 6502man » 09 oct. 2015 15:23

Extraordinaire :shock: la vitesse est stupéfiante :D

Félicitations.
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.

Avatar du membre
yo_fr
Messages : 1329
Enregistré le : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr » 09 oct. 2015 22:17

En utilisant une synchro qui ne passe pas par les 7474 (via l'octet de donnée Hector => Arduino), et donc plus avec des synchro temporelle, je suis passé à 55ko/sec :)

Avatar du membre
yo_fr
Messages : 1329
Enregistré le : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: HectorDuino

Message par yo_fr » 10 oct. 2015 17:34

Quelques optimisations plus tard, j'ai obtenu mes 60ko/s => 60.6 Ko/sec.

Ci dessous le coeur du player dans Hector :

Code : Tout sélectionner

BCL_VID_OFF:

		; Lecture des 4 octets de façon consécutive.
		; 1er => B
		; 2eme => D
		; 3eme => E
		; 4eme => C
		; Sachant que A sert tout le temps et 
		; HL est le pointeur d'écran
		
		IN		A,(PORTC)        ;  11  lecture portC 
		AND		$10              ;  7   PC4? Octet suivant D>H disponible ? ( BIT = 8 cycles!)
		JR		Z,BCL_VID_OFF	 ;  12/7 attente
		IN		A,(PORTB)        ;  11  Lecture PORTA (octet en provenance Disk)
		LD		B,A              ;  4   on mets de coté     

		
		LD		A,$05            ;  7   X0/X2 => PC0 / PC2 à 1
		OUT		(PORTC),A        ;  11  Validation octet envoyé sur PORTB
		LD		A,$07            ;  7   X0/X1/X2 => PC0 PC1 PC2   
		OUT		(PORTC),A		 ;  11  RAZ du bit X1 => validation lecture

	LD   A,3
	OUT (PORTA),A

		IN		A,(PORTB)        ; Lecture PORTA (octet en provenance Disk)
		LD		D,A              ; On mets dans reg D l'octet 2 reçu   

	LD   A,2
	OUT (PORTA),A

		IN		A,(PORTB)        ; 11 Lecture PORTA (octet en provenance Disk)
		LD		E,A              ; 4  On mets dans reg E l'octet 3 reçu

	LD   A,1
	OUT (PORTA),A

		IN		A,(PORTB)        ; 11 Lecture PORTA (octet en provenance Disk)
		LD		C,A              ; 4  On mets dans reg D l'octet 4 reçu   

		; Les 4 octets ont été reçus !
		
		;1er octet : offset dans B
		LD		A,B				;     Restauration octet lu !

		CP		0				; Offset reçu = 0 ???
		JR		Z,CONTROLE_VIDEO

		; Addition HL,A
		ADD		A,L
		LD		L,A
		ADC		A,H
		SUB		L 
		LD		H,A 

		; 1er octet de 4 pixels 
		LD		(HL),D			; Mise en place de l'octet

		; 2em octet de 4 pixels 
		INC		HL
		LD		(HL),E			; Mise en place de l'octet

		; 3em octet de 4 pixels 
		INC		HL
		LD		(HL),C			; Mise en place de l'octet
					
		JR  BCL_VID_OFF
	

CONTROLE_VIDEO:
		; Si on est ici c'est que l'on a recu un code offset à 0
		; On charge donc les 2 octets suivant dans HL
			
		LD		H,D
		LD		L,E
		
		; Si adresse = 01 => c'est que c'est fini on sort 
		;  -> 0100 ou 0001 ou 0101 ce qui ne rime à rien dans la ram Hector !
		LD		A,L
		OR		H
		
		CP 		1 
		JR		Z,VIDEO_OUT			; Si c'est la cas => on sort !
		
		; Sinon c'est que l'on souhaite écrire en mémoire !
		LD		(HL),C
		
		; et on relance
		JR		BCL_VID_OFF   ; non ce n'est pas une nouvelle frame, mais une nouvelle base de remplissage BCL_NEW_FRAME

Ainsi que le code Arduino correspondant :

Code : Tout sélectionner

      while( LPointeur <= L2 ) {  // Sur l'ensemble du fichier
                
        // On envoi l'octet N°1
        while ( digitalRead(I_WRITE_Pin) ){ // pas d'ecriture en cours ?     
         }
         PORTL = Octet;
         digitalWrite(SET_WRITE_Pin, LOW);
         digitalWrite(SET_WRITE_Pin, HIGH);

        // On envoi l'octet N°2
         while ( PINA != 3 ){ // Attente synchro depuis Hector    
         }
         PORTL = Octet2;
      
         while ( PINA != 2 ){ // Attente synchro depuis Hector     
         }
        
        // On envoi l'octet N°3
         PORTL = Octet3;
         while ( PINA != 1 ){ // Attente synchro depuis Hector
         }

        // On envoi l'octet N°4
         PORTL = Octet4;

       // Dés que c'est fait on peut y aller avec les autres octets!
       Octet = SD_L0_SpiRecvByte();   // echantillon du fichier
       Octet2 = SD_L0_SpiRecvByte();   // echantillon du fichier
       Octet3 = SD_L0_SpiRecvByte();   // echantillon du fichier
       Octet4 = SD_L0_SpiRecvByte();   // echantillon du fichier
       
       // C'est 4 octets que l'on vient de lire
       count=count+4;
       
       if (count >= 512 ) {
              // Tous les 512 octets il y a les CRC
              SD_L0_SpiRecvByte();            // premier octet CRC
              SD_L0_SpiRecvByte();            // deuxieme octet CRC
              count = 0;
              // attente octet 0xfe de debut de bloc suivant
              while(SD_L0_SpiRecvByte() != 0xfe);
        }
        LPointeur=LPointeur+4;
     }
Plus court cela sera très dur... :wink:

Je vais faire 1 ou 2 vidéo...

Répondre