Last active
April 29, 2018 19:19
-
-
Save nurpax/d32529b017f71fd0e77c89a9b5a5e328 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define POLYMASK_32 0xb4bcd35c | |
#define POLYMASK_31 0x7a5bc2e3 | |
#include <stdio.h> | |
#include <stdint.h> | |
uint32_t lfsr32; | |
uint32_t lfsr31; | |
int shift_lsfr(uint32_t* lfsr, uint32_t polynomial_mask) | |
{ | |
int feedback = *lfsr & 1; | |
*lfsr >>= 1; | |
if (feedback) { | |
*lfsr ^= polynomial_mask; | |
} | |
return *lfsr; | |
} | |
void init() | |
{ | |
lfsr32 = 0xabcde; | |
lfsr31 = 0x23456789; | |
} | |
uint32_t get_random() | |
{ | |
shift_lsfr(&lfsr32, POLYMASK_32); | |
uint32_t a = shift_lsfr(&lfsr32, POLYMASK_32); | |
uint32_t b = shift_lsfr(&lfsr31, POLYMASK_31); | |
return (a ^ b) & 0xffff; | |
} | |
int main() | |
{ | |
int histo[256] = {}; | |
init(); | |
for (int i = 0; i < 256*256*8; i++) { | |
uint32_t r = get_random() & 255; | |
histo[r]++; | |
printf("%d\n", r & 255); | |
} | |
printf("histogram\n"); | |
for (int i = 0; i < 256; i++) { | |
printf(" %03x", histo[i]); | |
if ((i & 15) == 15) { | |
printf("\n"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Original C version: https://gist.github.com/nurpax/d32529b017f71fd0e77c89a9b5a5e328 | |
.const POLYMASK_32 = $b4bcd35c | |
.const POLYMASK_31 = $7a5bc2e3 | |
// Initial seed | |
lfsr32: .byte $de, $bc, $0a, $00 | |
lfsr31: .byte $89, $67, $45, $23 | |
.macro shift_lsfr(lfsr, mask) { | |
lda lfsr+0 | |
and #1 | |
tax | |
lsr lfsr+3 | |
ror lfsr+2 | |
ror lfsr+1 | |
ror lfsr+0 | |
cpx #1 | |
bne skip_xor | |
.for (var i = 0; i < 4; i++) { | |
lda lfsr+i | |
eor #((mask>>(i*8)) & $ff) | |
sta lfsr+i | |
} | |
skip_xor: | |
} | |
// return 16-bits of random in A/X | |
rng: { | |
shift_lsfr(lfsr32, POLYMASK_32) | |
shift_lsfr(lfsr32, POLYMASK_32) | |
shift_lsfr(lfsr31, POLYMASK_31) | |
// Note: we only xor the 2 least-significant bytes as we only want 16-bit | |
// random out. | |
lda lfsr32+0 | |
eor lfsr31+0 | |
tax | |
lda lfsr32+1 | |
eor lfsr31+1 | |
rts | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
C code from https://www.maximintegrated.com/en/app-notes/index.mvp/id/4400