Comment donner un nombre aleatoire en asm ?

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

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

Comment donner un nombre aleatoire en asm ?

Message par rendomizer »

Et oui je me demande bien comment on fait pour obtenir un nombre aléatoire en asm...
Je ne suis qu'un utilisateur pas un pro
Markerror
Messages : 2121
Inscription : 31 oct. 2011 19:21
Localisation : Orléans
Contact :

Re: Comment donner un nombre aleatoire en asm ?

Message par Markerror »

Bonsoir,

Sur un Z80, il n'y a pas de moyen simple pour obtenir un nombre aléatoire. La seule instruction qui te donne une valeur numérique qui varie est le registre R, mais son comportement est logique et prévisible (valeur croissante sur 7 bits en fonction du nombre de NOP pris par les instructions exécutées avant de lire le contenu du registre.

Dans un soft que j'avais fait il y a déjà longtemps, Colors Lines, j'avais couplé l'usage de ce registre avec un compteur qui augmente et s'arrête en fonction d'une action de l'utilisateur (appui sur une touche par exemple). Le résultat était ensuite mixé avec une table fixe de valeurs tirées "au hasard" une fois pour toute. C'était pas parfait mais mieux que rien :-).
Avatar de l’utilisateur
rendomizer
Messages : 413
Inscription : 17 juin 2016 21:00
Contact :

Re: Comment donner un nombre aleatoire en asm ?

Message par rendomizer »

Merci pour cette réponse. Je pensais qu'il y avait une astuce autre qu'une simple routine de balayage de la mémoire vive ou du registre R :lol: J'ai pensé a ton idée d'une action sur une touche et un compteur ! je pense que c'est une bonne idée finalement. :D
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 donner un nombre aleatoire en asm ?

Message par __sam__ »

Traditionnellement dans la plupart des langages (BASIC, C, FORTH, PASCAL), on utilise un générateur pseudo-aléatoire congruentiel linéaire, mais les résultats sont plutôt peu aléatoires. En effet, il apparait des motifs réguliers quand on remplie une grille 2d (cf le calcul de PI par Dominique), preuve d'une très forte correlations entre les valeurs successives.
Image
En plus cet algo utilisant une multiplication 16 bits est plutôt lent sur les cpu 8 bits.

Il existe des générateurs à base de décalages et xor logiques bien plus rapides et un peu plus aléatoires (en particulier parce que la graine/état interne est sur plus de 16 bits): https://en.wikipedia.org/wiki/Xorshift. Ceux la sont très bons et très efficaces sur les micros 8bits, par exemple sur Z80.

Cependant comme sur 6809 la multiplication 8bitsx8bits->16bits est très rapide, j'ai un code rikiki qui sort des nombres pseudo-aléatoire de bonne facture (période de 31870):

Code : Tout sélectionner

rnd	ldd	#3*256+249 ; graine (ne pas changer, celle là produit une longue période)
	mul	; D=A*B 8x8->16 bits. Ultra rapide sur 6809 (11 cycles)
rnd1	addd	#0 ; 
	sta	<rnd1+2
	stb	<rnd+1+2
	rts ; Reg A écrasé. Resultat dans le reg B de 0 à 255
Malgrès l'utilisation d'une multiplication ca n'est pas un générateur linéaire congruentiel, mais un générateur adapté pour 8bits inspirés des générateurs "multiply with carry" qui ont de meilleurs propriétés aléatoires que les générateurs linéaires congruentiels. On retrouve une version Z80 de ce genre de générateur en bas de: http://chuntey.arjunnair.in/?cat=4

Après il faut tirer une certaines quantité variable de nombres aléatoires si on ne veut pas sans arret ressortir indéfiniment la même série de nombre à chaque fois qu'on lance le programme. Pour cela il faut une source d'entropie (nom savant pour parler de bruit aléatoire). Sur les micros 8 bits elles sont rares. Les compteurs VIDEO peuvent le faire, mais le mieux est de faire une boucle d'attente tout en demandant à l'utilisateur d'appuyer sur une touche. On profitte de cette boucle pour tirer un nouveau nb aléatoire pour rien à chaque tour. Mais comme le nb de tours dépend de la vitesse de réaction de l'utilisateur (chose très variable), cela pré-initialise les générateurs avec une graine suffisamment aléatoire en pratique.
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
Répondre