comment fait on une attente en asm z80 ?

Cette catégorie traite de développements récents pour nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

Répondre
Avatar de l’utilisateur
rendomizer
Messages : 413
Inscription : 17 juin 2016 21:00
Contact :

comment fait on une attente en asm z80 ?

Message par rendomizer »

Sans avoir recour a des tonne de lignes pour freiner la bête Je serai bien curieux de savoir comment on fait un delay en asm ?
Dernière modification par rendomizer le 26 juil. 2017 08:20, modifié 2 fois.
Je ne suis qu'un utilisateur pas un pro
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: comment fait on un delay en asm ?

Message par __sam__ »

Ben on fait une boucle vide avec un compteur qui va de N à 0, et une' fois le 0 atteint on sort de la boucle. En comptant les cycles, on adapte la valeur de N pour avoir le délais d'attente souhaité. C'est quoi le soucis ?
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: comment fait on un delay en asm ?

Message par Daniel »

On fait une boucle. Le délai est égal au nombre de cycles des instructions de la boucle multiplié par la valeur du compteur de boucle.
[posté en même temps que __sam__ :wink: ]
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
rendomizer
Messages : 413
Inscription : 17 juin 2016 21:00
Contact :

Re: comment fait on un delay en asm ?

Message par rendomizer »

J'ai fait cette fameuse boucle mais elle prend de la place ! comme je débute en asm je pense que je dois pas être tres économique en code !

Code : Tout sélectionner

_timer:                              
      ld a,0
_gaga:      
      inc a
      cp 255
      jr nz,_gaga
      nop
      nop
      ld a,0
_gaga2:      
      inc a
      cp 255
      jr nz,_gaga2
      nop
      nop
      ld a,0
_gaga3:
      inc a      
      cp 255
      jr nz,_gaga3
      nop
      nop 
      ld a,0
_gaga4:      
      inc a      
      cp 255
      jr nz,_gaga4
      nop
      nop
      ld a,0
_gaga5:      
      inc a
      cp 255
      jr nz,_gaga5
      nop
      nop 
      ld a,0
_gaga6:      
      inc a      
      cp 255
      jr nz,_gaga6
      nop
      nop
      ld a,0
_gaga7:      
      inc a      
      cp 255
      jr nz,_gaga7
      nop
      nop 
      ld a,0
_gaga8:      
      inc a      
      cp 255
      jr nz,_gaga8
      nop
      nop 
      ld a,0
_gaga9:      
      inc a      
      cp 255
      jr nz,_gaga9
      nop
      nop
      ld a,0
_gaga10:      
      inc a      
      cp 255
      jr nz,_gaga10
      nop
      nop 
      ld a,0
_gaga11:      
      inc a
      cp 255
      jr nz,_gaga11
      nop
      nop
      ld a,0      
_gaga12:      
      inc a
      cp 255
      jr nz,_gaga12
      nop
      nop 
      ld a,0
_gaga13:      
      inc a
      cp 255
      jr nz,_gaga13
      nop       
      nop 
      ld a,0
_gaga14:      
      inc a
      cp 255
      jr nz,_gaga14
      nop
      nop
      ld a,0
_gaga15:      
      inc a
      cp 255
      jr nz,_gaga15
      nop
      nop 
      ld a,0
_gaga16:      
      inc a
      cp 255
      jr nz,_gaga16
      nop
      nop
      ld a,0
_gaga17:      
      inc a
      cp 255
      jr nz,_gaga17
      nop
      nop 
      ld a,0
_gaga18:      
      inc a
      cp 255
      jr nz,_gaga18
      nop
      nop 
      ld a,0
_gaga19:      
      inc a
      cp 255
      jr nz,_gaga19
      nop
      nop
      ld a,0
_gaga20:      
      inc a
      cp 255
      jr nz,_gaga20
      nop
      nop
      ld a,0
_gaga21:      
      inc a
      cp 255
      jr nz,_gaga21
      nop
      nop
      ld a,0
_gaga22:      
      inc a
      cp 255
      jr nz,_gaga22
      nop
      nop
      ld a,0
_gaga23:
      inc a
      cp 255
      jr nz,_gaga23
      nop
      nop
      ld a,0
_gaga24:      
      inc a
      cp 255
      jr nz,_gaga24
      jp _debut
Je ne suis qu'un utilisateur pas un pro
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: comment fait on un delay en asm ?

Message par __sam__ »

Déjà au lieu de compter de 0 à 255 ce qui inclue un "cp 255", compte plutôt dans le sens inverse de 256 (0) à 0, et là tu économises ce "cp" ce qui fait une instruction en moins. Ensuite je ne comprends pas pourquoi il y a deux "nop" qui suivent. Ils ne servent à rien. Enfin, au lieu de dérouler la boucle en mémoire, fais 2 boucles imbriquées en sauvant la valeur de ton accumulateur sur la pile. Je ne pourrais pas t'en dire plus qui soit généraliste car après il faut connaitre ton cpu cible. En pseudo-asm ca donnerait quelque chose comme:

Code : Tout sélectionner

  lda #10 (10 fois la boucle de 255)
boucle1:
  psha (empile l'accu... je ne sais pas la syntaxe exacte)
  lda #0
boucle2:
  dec
  jr nz,boucle2
  pula (recup de l'accu empilé)
  dec
  jr ns,boucle1
Dernière modification par __sam__ le 24 juil. 2017 08:23, modifié 2 fois.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: comment fait on un delay en asm ?

Message par Daniel »

Effectivement, avec plus de 120 instructions dans ton programme, ce n'est pas très économique. On doit pouvoir faire la même temporisation avec 3 ou 4 instructions, les spécialistes du Z80 vont certainement pouvoir donner un exemple. Avec un 6809 on le fait en 3 instructions :

Code : Tout sélectionner

TEMPO
  LDX  #$xxxx    ; compteur de boucle (xxxx determine la duree de la temporisation)
BOUCLE     
  LEAX -1,X      ; decrementation du compteur de boucle
  BNE BOUCLE     ; boucle tant que le compteur n'est pas nul
Daniel
L'obstacle augmente mon ardeur.
joaopa
Messages : 512
Inscription : 14 sept. 2013 12:17

Re: comment fait on un delay en asm ?

Message par joaopa »

Une boucle de temporisation en Z80:

Code : Tout sélectionner

    LD BC,duree (sur 16 bits bien évidemment)
bcle:
    DEC BC
    LD A,B
    OR C
    JR NZ,bcle
C'est l'une des faiblesses des Z80. On est quasiment tout le temps obligé de passer par l'accumulateur A pour comparer entre eux les autres registres. Même l'instruction DEC qui pose un drapeau Z (ou NZ) si le registre est ou non à zéro, ne pose aucun drapeau si elle travaille sur un pseudo-registre 16bits. Et pas de bol, l'accumulateur A est couplé avec le registre F qui tient les drapeaux. Il n'y a donc pas d'instruction qui puisse modifier le registre AF. On ne peut donc pas s'en servir comme compteur.

EDIT: Un modérateur peut-il changer le <<delay>> du titre en <<attente>>. Merci d'avance
Avatar de l’utilisateur
rendomizer
Messages : 413
Inscription : 17 juin 2016 21:00
Contact :

Re: comment fait on une attente en asm ?

Message par rendomizer »

merci Joaopa !
Je ne suis qu'un utilisateur pas un pro
Avatar de l’utilisateur
Papy.G
Modérateur
Messages : 3047
Inscription : 10 juin 2014 13:40
Localisation : Haute-Garonne/Gers

Re: comment fait on une attente en asm ?

Message par Papy.G »

Sinon, si ton programme a fait ce qui lui était imparti, tu peux peut-être suspendre le processeur (halt sur Z80?) jusqu'à la prochaine interruption, voire même en plus un vecteur d'interruption qui compte un certain nombre d'interruptions d'un type particulier (synchro écran par exemple) pour avoir une sorte de base de temps. :|
Le VG est pas sur piles, donc c'est pas trop pour la consommation d'énergie, mais ça fait peut-être moins chauffer que de faire des boucles de gaspillage de TM. :P
Soyez exigeants, ne vous contentez pas de ce que l'on vous vend.
Demandez-en plus, ou faites-le vous-même.
Avatar de l’utilisateur
6502man
Messages : 12286
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: comment fait on une attente en asm ?

Message par 6502man »

Il y aussi l'interruption du VG5000, pour temporiser/synchroniser, je l'ai utilisé pour mon player AY-3 pour la cartouche VG-5301 que j'ai réalisé et ça fonctionne très bien :wink:
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
Avatar de l’utilisateur
Mokona
Messages : 1040
Inscription : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: comment fait on une attente en asm ?

Message par Mokona »

Oui ça marche assez bien. En se branchant sur l'interruption vidéo du VG5000, on peut gérer un compteur (sensible aux di/ei par contre)
Avatar de l’utilisateur
Papy.G
Modérateur
Messages : 3047
Inscription : 10 juin 2014 13:40
Localisation : Haute-Garonne/Gers

Re: comment fait on une attente en asm z80 ?

Message par Papy.G »

Les frappes clavier ne génèrent pas d'interruptions dans le VG5000µ? :?
C'est quoi di/ei? :oops:
Soyez exigeants, ne vous contentez pas de ce que l'on vous vend.
Demandez-en plus, ou faites-le vous-même.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: comment fait on une attente en asm z80 ?

Message par __sam__ »

di/ei: disable interrupts / enable interupts. Un grand classique de tous les codeurs qui veulent gagner des cycle (en tout cas ne pas s'en faire voler par les routines de service des interruptions)
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
Mokona
Messages : 1040
Inscription : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: comment fait on une attente en asm z80 ?

Message par Mokona »

La lecture du clavier est "manuelle" au besoin.

Dans l'éditeur, la lecture est faite "manuellement" (par un call) après un halt. Sur Z80, un halt attend la prochaine interruption pour réveiller le processeur. Du coup, la lecture du clavier est faite après chaque IRQ (lancée 50 fois par seconde il me semble).

La fonction BASIC KEY fait un appel direct aussi.

INPUT a l'air de gérer ses appels au clavier aussi.

Le décodage se fait ensuite par lectures successives des ports 0x87 à 0x80 et dès qu'un port renvoi quelque chose, décode la valeur (et d'après la doc, fait le debouncing, mais je n'ai pas analysé cette partie encore).
Répondre