mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-04-28 08:38:09 +00:00
random: trying to find a reasonable random number generator
This commit is contained in:
parent
6cb3904828
commit
14bdb6cfa1
26
random/Makefile
Normal file
26
random/Makefile
Normal file
@ -0,0 +1,26 @@
|
||||
CC = gcc
|
||||
CFLAGS = -O2 -Wall
|
||||
LFLAGS =
|
||||
|
||||
all: random16 random8 #random15
|
||||
|
||||
###
|
||||
|
||||
random16: random16.o
|
||||
$(CC) $(LFLAGS) -o random16 random16.o
|
||||
|
||||
random16.o: random16.c
|
||||
$(CC) $(CFLAGS) -c random16.c
|
||||
|
||||
###
|
||||
|
||||
random8: random8.o
|
||||
$(CC) $(LFLAGS) -o random8 random8.o
|
||||
|
||||
random8.o: random8.c
|
||||
$(CC) $(CFLAGS) -c random8.c
|
||||
|
||||
###
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o random16 random8 random15
|
9
random/README
Normal file
9
random/README
Normal file
@ -0,0 +1,9 @@
|
||||
Trying to find a good pseudo-random number generator for 6502
|
||||
|
||||
I had been using the "random16" one here, but at least on Peasant's Quest
|
||||
when used to generate a 0-31 random value it seemed to have "0" and "17"
|
||||
come up way more than exected
|
||||
|
||||
the "random8" one here is better, but it's really only 7 bits as you can't
|
||||
actually generate a 0 and code might fail if you never get a 0 result?
|
||||
|
109
random/random16.c
Normal file
109
random/random16.c
Normal file
@ -0,0 +1,109 @@
|
||||
#include <stdio.h>
|
||||
|
||||
// 16-bit 6502 Random Number Generator
|
||||
|
||||
// Linear feedback shift register PRNG by White Flame
|
||||
// http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng
|
||||
|
||||
// The Apple II KEYIN routine increments this field
|
||||
//while waiting for keypress
|
||||
|
||||
//SEEDL = $4E
|
||||
//SEEDH = $4F
|
||||
|
||||
//XOR_MAGIC = $7657 ; "vW"
|
||||
|
||||
static unsigned short xor_magic=0x7657;
|
||||
//static unsigned short xor_magic=0x002d;
|
||||
static unsigned short seed=0x0000;
|
||||
|
||||
// ;=============================
|
||||
// ; random16
|
||||
// ;=============================
|
||||
|
||||
unsigned short random16(void) {
|
||||
|
||||
if ((seed&0xff)!=0) {
|
||||
if ((seed&0x8000)==0) {
|
||||
// noEor
|
||||
seed<<=1;
|
||||
return seed;
|
||||
}
|
||||
else {
|
||||
// doEor
|
||||
seed<<=1;
|
||||
seed=seed^xor_magic;
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if bottom 0
|
||||
if (((seed>>8)&0xff)==0) {
|
||||
seed<<=1;
|
||||
seed=seed^xor_magic;
|
||||
return seed;
|
||||
}
|
||||
|
||||
else {
|
||||
if ((seed & 0x8000)==0) {
|
||||
seed<<=1;
|
||||
return seed;
|
||||
}
|
||||
else {
|
||||
seed<<=1;
|
||||
seed=seed^xor_magic;
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int i,r;
|
||||
|
||||
for(i=0;i<65537;i++) {
|
||||
r=random16();
|
||||
printf("%04hx %04hx\n",r,r&0x1f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// lda SEEDL ; 3
|
||||
// beq lowZero ; $0000 and $8000 are special values ; 2
|
||||
|
||||
// asl SEEDL ; Do a normal shift ; 5
|
||||
// lda SEEDH ; 3
|
||||
// rol ; 2
|
||||
// bcc noEor ; 2
|
||||
|
||||
//doEor:
|
||||
// ; high byte is in A
|
||||
|
||||
|
||||
// eor #>XOR_MAGIC ; 2
|
||||
// sta SEEDH ; 3
|
||||
// lda SEEDL ; 3
|
||||
// eor #<XOR_MAGIC ; 2
|
||||
// sta SEEDL ; 3
|
||||
// rts ; 6
|
||||
|
||||
//lowZero:
|
||||
// ; 1
|
||||
// lda SEEDH ; 3
|
||||
// beq doEor ; High byte is also zero ; 3
|
||||
// ; so apply the EOR
|
||||
// ; -1
|
||||
// ; wasn't zero, check for $8000
|
||||
// asl ; 2
|
||||
// beq noEor ; if $00 is left after the shift ; 2
|
||||
// ; then it was $80
|
||||
// bcs doEor ; else, do the EOR based on the carry ; 3
|
||||
|
||||
//noEor:
|
||||
// ; 1
|
||||
// sta SEEDH ; 3
|
||||
|
||||
// lda SEEDL ; always return SEEDL
|
||||
// rts ; 6
|
47
random/random8.c
Normal file
47
random/random8.c
Normal file
@ -0,0 +1,47 @@
|
||||
// http://www.6502.org/users/mycorner/6502/code/prng.html
|
||||
|
||||
//; returns pseudo random 8 bit number in A. Affects A. (r_seed) is the
|
||||
//; byte from which the number is generated and MUST be initialised to a
|
||||
//; non zero value or this function will always return zero. Also r_seed
|
||||
//; must be in RAM, you can see why......
|
||||
|
||||
//rand_8
|
||||
// LDA r_seed ; get seed
|
||||
// ASL ; shift byte
|
||||
// BCC no_eor ; branch if no carry
|
||||
//
|
||||
// EOR #$CF ; else EOR with $CF
|
||||
//no_eor
|
||||
// STA r_seed ; save number as next seed
|
||||
// RTS ; done
|
||||
|
||||
//r_seed
|
||||
// .byte 1 ; prng seed byte, must not be zero
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
unsigned char r_seed=1;
|
||||
|
||||
int rand8(void) {
|
||||
if (r_seed&0x80) {
|
||||
r_seed<<=1;
|
||||
r_seed^=0xcf;
|
||||
}
|
||||
else {
|
||||
r_seed<<=1;
|
||||
}
|
||||
return r_seed;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int i,r;
|
||||
|
||||
for(i=0;i<1024;i++) {
|
||||
r=rand8();
|
||||
printf("%02X m%02X\n",r,r&0x1f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user