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 : Carl, Papy.G, fneck

Répondre
Avatar du membre
rendomizer
Messages : 202
Enregistré le : 17 juin 2016 21:00
Contact :

comment fait on une attente en asm z80 ?

Message par rendomizer » 23 juil. 2017 21:08

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 ?
Modifié en dernier par rendomizer le 26 juil. 2017 08:20, modifié 2 fois.
le mot de passe c'est quoi ? quoi.

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

Re: comment fait on un delay en asm ?

Message par __sam__ » 23 juil. 2017 21:54

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+, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8. New Teo 1.8.4 8)

Daniel
Messages : 10425
Enregistré le : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: comment fait on un delay en asm ?

Message par Daniel » 23 juil. 2017 21:57

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 du membre
rendomizer
Messages : 202
Enregistré le : 17 juin 2016 21:00
Contact :

Re: comment fait on un delay en asm ?

Message par rendomizer » 24 juil. 2017 06:32

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
le mot de passe c'est quoi ? quoi.

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

Re: comment fait on un delay en asm ?

Message par __sam__ » 24 juil. 2017 08:18

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
Modifié en dernier par __sam__ le 24 juil. 2017 08:23, modifié 2 fois.
Samuel.
A500 Vampire V2+, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8. New Teo 1.8.4 8)

Daniel
Messages : 10425
Enregistré le : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: comment fait on un delay en asm ?

Message par Daniel » 24 juil. 2017 08:19

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 : 380
Enregistré le : 14 sept. 2013 12:17

Re: comment fait on un delay en asm ?

Message par joaopa » 24 juil. 2017 09:22

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 du membre
rendomizer
Messages : 202
Enregistré le : 17 juin 2016 21:00
Contact :

Re: comment fait on une attente en asm ?

Message par rendomizer » 24 juil. 2017 16:03

merci Joaopa !
le mot de passe c'est quoi ? quoi.

Avatar du membre
Papy.G
Modérateur
Messages : 1733
Enregistré le : 10 juin 2014 13:40
Localisation : Nantes/La Roche sur Yon

Re: comment fait on une attente en asm ?

Message par Papy.G » 24 juil. 2017 22:59

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 du membre
6502man
Messages : 8968
Enregistré le : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: comment fait on une attente en asm ?

Message par 6502man » 25 juil. 2017 17:34

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 du membre
Mokona
Messages : 301
Enregistré le : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: comment fait on une attente en asm ?

Message par Mokona » 25 juil. 2017 20:53

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 du membre
Papy.G
Modérateur
Messages : 1733
Enregistré le : 10 juin 2014 13:40
Localisation : Nantes/La Roche sur Yon

Re: comment fait on une attente en asm z80 ?

Message par Papy.G » 26 juil. 2017 09:57

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 : 4022
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: comment fait on une attente en asm z80 ?

Message par __sam__ » 26 juil. 2017 10:48

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+, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8. New Teo 1.8.4 8)

Avatar du membre
Mokona
Messages : 301
Enregistré le : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: comment fait on une attente en asm z80 ?

Message par Mokona » 26 juil. 2017 18:20

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