No agora quase remoto cinco de maio o Flávio “TK90X Fan” Matsumoto publicou em seu blog uma rotina bastante interessante para a geração de números (pseudo)aleatórios em assembly Z80. Como o próprio Flávio comenta, a rotina está bastante otimizada e também trata-se de código auto-modificável (basicamente a cada execução ele mexe em partes dele mesmo alterando certos valores — algo como mudar as variáveis originais).
Confesso que conhecia uma rotina bem mais simples e enxuta que tenho usado em alguns programas. A rotina é de autoria de Milos “baze” Bazelides e baseado na seguinte fórmula:
x[i + 1] = (5 * x[i] + 1) mod 256
E que em assembly de Z80 fica assim:
RANDOM: ld a,0 ld b,a add a,a add a,a add a,b inc a ld (RANDOM+1),a ; atualiza o seed ret
O código original é para números de 8-bit (0 a 255) mas há também uma versão para números de 16-bit (0 a 65535) e ambos encontram-se na página pessoal dele, junto com muitas outras dicas e trechos interessantes de código. No caso específico do MSX eu resolvi cuidar para que o “aleatório” ficasse um pouco mais aleatório inicializando a semente assim:
ld a,(JIFFY) ; inicializo a semente do meu gerador ld (RANDOM+1),a ; de números pseudo-aleatórios
A variável de ambiente JIFFY (0xFC9E e 0XFC9F) contém o número de interrupções do VDP e é o valor retornado pela função TIME do MSX-BASIC. Logo o trecho acima é algo parecido a fazer o bom e velho “R=RND(-TIME)” que todo mundo já usou uma vez ou outra na vida.
Oi, Giovanni.
Obrigado pela menção à postagem do meu blog. De fato existem várias rotinas de geração de números pseudo-aleatórios e, no meu demo, quis experimentar a rotina de Patrick Rak. Não tinha entretanto uma necessidade de grande elaboração nos valores produzidos, foi só curiosidade mesmo. Mesmo assim, mostrou-se muito superior ao RND do BASIC do TK90X.
Um grande abraço.