unsigned char rng()
{
static unsigned char history = 0x01; /* Seed, choose whatever you like! */
history <<= 1;
history |= (((history&2)>>1) ^ ((history&128)>>7));
return history&3; /* 2-bit output */
}
01136 ;*******************************************************************
01137 ;
01138 ; Random Number Generator
01139 ;
01140 ; This routine generates a 16 Bit Pseudo Sequence Random Generator
01141 ; It is based on Linear shift register feedback. The sequence
01142 ; is generated by (Q15 xorwf Q14 xorwf Q12 xorwf Q3 )
01143 ;
01144 ; The 16 bit random number is in location RandHi(high byte)
01145 ; & RandLo (low byte)
01146 ;
01147 ; Before calling this routine, make sure the initial values
01148 ; of RandHi & RandLo are NOT ZERO
01149 ; A good chiose of initial random number is 0x3045
01150 ;*******************************************************************
01151 ;
0311 01152 Random16
0311 1A19 01153 rlcf RandHi,W
0312 0C19 01154 xorwf RandHi,W
0313 1B0A 01155 rlcf WREG, F ; carry bit = xorwf(Q15,14)
01156 ;
0314 1D19 01157 swapf RandHi, F
0315 1C18 01158 swapf RandLo,W
0316 230A 01159 rlncf WREG, F
0317 0C19 01160 xorwf RandHi,W ; LSB = xorwf(Q12,Q3)
0318 1D19 01161 swapf RandHi, F
0319 B501 01162 andlw 0x01
031A 1B18 01163 rlcf RandLo, F
031B 0D18 01164 xorwf RandLo, F
031C 1B19 01165 rlcf RandHi, F
031D 0002 01166 return
Well, my contribution uses 4 ram locations but does produce pretty random numbers. You xor together bits 30 and 27 and feed that into the bottom bit with the other bits shifted left one. You can normally do AND #$48 and ADD #$38 (with the MS byte) to get the random bit into bit 7 of the accumulator. The whole thing is about 7 instructions, call it twice and you have two random bits. I did post a Swordfish version but cant find it.
...
How about ADC with the analog input pin floating? You're not going to know what number you will be getting and it should be pretty random. How fast do you want it to be?
unsigned char rng()
{
static unsigned char history = 0x01; /* Seed, choose whatever you like! */
history <<= 1;
history |= (((history&2)>>1) ^ ((history&128)>>7));
return history&3; /* 2-bit output */
}
Rand rlf Random,w ;shift and move to W
andlw 0x82 ;keep bits 7 and 1
addlw 0x7e ;xor into bit 7
addlw 0x80 ;move to carry bit
rlf Random,f ;shift into seed
return
;==============================================================================
; test franchies simple 1byte RNG
; using pommies clever asm code
;==============================================================================
; config for 16F628
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _MCLRE_ON & _BODEN_ON & _LVP_OFF
include <p16f628.inc>
CBLOCK 0x20 ; start of ram in 16F628
bitcount ; number of bits to make
random ; the 1byte random number
ENDC
;==============================================================================
; Code here
org 0x000 ;
reset
goto main ;
;==============================================================================
main
movlw b'11010010' ; seed RNG
movwf random ;
; loop here and make 8 random bits
rng_make8bits
movlw d'8' ;
movwf bitcount ;
rng_make1bit
rlf random,w ; shift and move to w
andlw b'10000010' ; keep only bit7 and bit1
addlw b'01111110' ; xor bit7^bit1 into bit7 (brilliant)
; truth table of (addlw b'01111110');
; (7^1 -> 7)
; 1^1 = 0
; 0^0 = 0
; 1^0 = 1
; 0^1 = 1
addlw b'10000000' ; move w bit7 into carry
rlf random,f ; put carry in bit0
; now it has generated 1 random bit
decfsz bitcount,f;
goto rng_make1bit ;
; now it has generated 8 random bits
; (breakpoint here for testing)
goto rng_make8bits ;
end
(rng bit = 7^1, seed = 11010010)
11000110111101101011011001001000
11100001011111001010111001101000
10011110001010000110000010000001
11111101010100110011101110100101
; 5^1
rlf random,w ; shift and move to w
andlw b'00100010' ; keep only bit5 and bit1
addlw b'00011110' ; xor bit5^bit1 into bit5 (brilliant)
andlw b'00100000' ; keep only bit5
addlw b'11100000' ; move w bit5 into carry
rlf random,f ; put carry in bit0
(rng bit = 5^1, seed = 11010010)
11100101110010111001011100101110
01011100101110010111001011100101
(repeats pattern 1110010)
(rng bit = 5^1, seed = 10000010)
00011111010100110001000011111010
10011000100001111101010011000100
(repeats 000111110101001100010)
;==============================================================================
; test franchies simple 1byte RNG
; using pommies clever asm code
; plus romans kludge to kill xxxx0000 and xxxx1111
;==============================================================================
; config for 16F628
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _MCLRE_ON & _BODEN_ON & _LVP_OFF
include <p16f628.inc>
CBLOCK 0x20 ; start of ram in 16F628
bitcount ; number of bits to make
random ; the 1byte random number
ENDC
;==============================================================================
; Code here
org 0x000 ;
reset
goto main ;
;==============================================================================
main
movlw b'11010010' ; seed RNG
movwf random ;
; loop here and make 8 random bits
rng_make8bits
movlw d'8' ;
movwf bitcount ;
rng_make1bit
rlf random,w ; shift and move to w
andlw b'10000010' ; keep only bit7 and bit1
addlw b'01111110' ; xor bit7^bit1 into bit7 (brilliant)
; truth table of (addlw b'01111110');
; (7^1 -> 7)
; 1^1 = 0
; 0^0 = 0
; 1^0 = 1
; 0^1 = 1
addlw b'10000000' ; move w bit7 into carry
rlf random,f ; put carry in bit0
; test if random is xxxx1111 or xxxx0000
; if so; invert the new random bit (bit0)
incf random,w ; is now xxxx0000 or xxxx0001
andlw b'00001111' ; keep last 4 bits
sublw d'1' ; sub to test w
movlw b'00000000' ; load w ready to NOT invert random bit0
skpnc ; skip if w was > 1
movlw b'00000001' ; load w to invert random bit0
xorwf random,f ; invert bit0 if needed
; now it has generated 1 random bit
decfsz bitcount,f;
goto rng_make1bit ;
; now it has generated 8 random bits
; (breakpoint here for testing)
goto rng_make8bits ;
end
(New test (7^1) and check for 0000 and 1111
and invert bit0 if needed.)
11000110111010010110001101110100
10110001101110100101100011011101
00101100011011101001011000110111
01001011000110111010010110001101
(has a 34bit repeat...)
;==============================================================================
; test franchies simple 1byte RNG
; using pommies clever asm code
; plus romans kludge to kill xxxx0000 and xxxx1111
;==============================================================================
; config for 16F628
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _MCLRE_ON & _BODEN_ON & _LVP_OFF
include <p16f628.inc>
CBLOCK 0x20 ; start of ram in 16F628
bitcount ; number of bits to make
random ; the 1byte random number
ENDC
;==============================================================================
; Code here
org 0x000 ;
reset
goto main ;
;==============================================================================
main
movlw b'11010010' ; seed RNG
movwf random ;
; loop here and make 8 random bits
rng_make8bits
movlw d'8' ;
movwf bitcount ;
rng_make1bit
rlf random,w ; shift and move to w
andlw b'10000010' ; keep only bit7 and bit1
addlw b'01111110' ; xor bit7^bit1 into bit7 (brilliant)
; truth table of (addlw b'01111110');
; (7^1 -> 7)
; 1^1 = 0
; 0^0 = 0
; 1^0 = 1
; 0^1 = 1
addlw b'10000000' ; move w bit7 into carry
rlf random,f ; put carry in bit0
; test if random is xxxx1111 or xxxx0000
; if so; invert the new random bit (bit0)
incf random,w ; is now xxxx0000 or xxxx0001
andlw b'00001111' ; keep last 4 bits
sublw d'1' ; sub to test w
movlw b'00000000' ; load w ready to NOT invert random bit0
skpnc ; skip if w was > 1
movlw b'00001001' ; load w to invert random bit0 (and bit3)
xorwf random,f ; invert bit0 if needed
; now it has generated 1 random bit
decfsz bitcount,f;
goto rng_make1bit ;
; now it has generated 8 random bits
; (breakpoint here for testing)
goto rng_make8bits ;
end
(7^1, seed 11010010, on 1111 or 0000 we
xor random with 00001001);
11000110011010001000110111010001
00011011101000100011011101000100
01100110100010011100110100010011
10011010001001110011010001000110
01101000100011011101000100011011
10100010001101110100010001100110
10001001110011010001001110011010
00100111001101000100011001101000
movlw b'00001001' ; load w to invert random bit0 (and bit3)
skpnc ; skip if w was > 1
xorwf random,f ; invert bit0 if needed
rlf random,w ; shift and move to w
andlw b'10000010' ; keep only bit7 and bit1
addlw b'01111110' ; xor bit7^bit1 into bit7 (brilliant)
addlw b'10000000' ; move w bit7 into carry
rlf random,f ; put carry in bit0
; test if random is xxxx1111 or xxxx0000
; if so; invert the new random bit (bit0)
incf random,w ; is now xxxx0000 or xxxx0001
andlw b'00001111' ; keep last 4 bits
sublw d'1' ; sub to test w
movlw b'00001001' ; load w to invert random bit0 (and bit3)
skpnc ; skip if w was > 1
xorwf random,f ; invert bit0 if needed
movlw d'46' ; main toggle on 128/46
addwf rngloop,f ;
(128/46 =2.78260869565)
10001110011100011100011000111000
11000111000111001110001110001100
01110001100011100011100111000111
00111000111000110001110001110011
; make a random bit in rngloop,7 (total 7 instructions)
movlw d'46' ; main toggle on 128/46
addwf rngloop,f ;
movlw d'104' ; force to toggle 256/104
addwf rngforced,f ;
movlw (d'128'-d'46') ; this forces temp,7 to toggle
skpnc ;
addwf rngloop,f ;
(128/46 =2.78260869565,
+forced toggle on 256/104
=2.46153846153)
11001001101100100110110100010111
01000101110100100110110010011011
01000101110100010111010010011011
00100110110100010111010011011001
00100110110010011011001011011001
00110110010010011011001011101000
10110110010011011001001011101000
10111010001011011001001101100100
;==============================================================================
; "Dual tuned" RNG
; open-source - RomanBlack 13 Sept 2009
; uses dual loops to set the RNG max stringlength and spread
;==============================================================================
; config for 16F628
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _MCLRE_ON & _BODEN_ON & _LVP_OFF
include <p16f628.inc>
CBLOCK 0x20 ; start of ram in 16F628
bitcount ; number of bits to make
random ; the 1byte random number
rngloop ; for main RNG loop
rngforced ; for "forced toggle" loop
ENDC
;==============================================================================
; Code here
org 0x000 ;
reset
goto main ;
;==============================================================================
main
; loop here and make 8 random bits
rng_make8bits
movlw d'8' ;
movwf bitcount ;
rng_make1bit
; make a random bit in rngloop,7 (total 7 instructions)
movlw d'46' ; main toggle on 128/46
addwf rngloop,f ;
movlw d'104' ; force to toggle 256/104
addwf rngforced,f ;
movlw (d'128'-d'46') ; this forces rngloop,7 to toggle
skpnc ;
addwf rngloop,f ;
; the new random bit is in rngloop,7
rlf rngloop,w ; get rngloop,7 in carry
rlf random,f ; put carry in random,0
; now it has generated 1 random bit
decfsz bitcount,f;
goto rng_make1bit ;
; now it has generated 8 random bits
; (breakpoint here for testing)
goto rng_make8bits ;
end
(128/46 =2.78260869565,
forced toggle on 256/104
=2.46153846153)
11001001101100100110110100010111
01000101110100100110110010011011
01000101110100010111010010011011
00100110110100010111010011011001
00100110110010011011001011011001
00110110010010011011001011101000
10110110010011011001001011101000
10111010001011011001001101100100
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?