Skip to content

Instantly share code, notes, and snippets.

@nurpax
Last active April 29, 2018 19:19
Show Gist options
  • Save nurpax/d32529b017f71fd0e77c89a9b5a5e328 to your computer and use it in GitHub Desktop.
Save nurpax/d32529b017f71fd0e77c89a9b5a5e328 to your computer and use it in GitHub Desktop.
#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");
}
}
}
// 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
}
@nurpax
Copy link
Author

nurpax commented Apr 29, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment