Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* http://www.housedillon.com/?p=1272
- * Written by iskunk (Daniel Richard G.)
- * THIS FILE IS IN THE PUBLIC DOMAIN
- *
- * Program to emulate the CM-5's "random and pleasing" LED panel mode
- * (revision 4)
- */
- #include <stdio.h>
- #include <stdint.h>
- #include <string.h>
- #include <unistd.h>
- #include <assert.h>
- #define NUM_ROWS 32 /* unique rows */
- #define NUM_ROWS_DISPLAYED 106 /* rows in front panel display */
- static uint16_t get_next_rnum_bit(uint16_t prev_rnum, uint16_t *pbit_out)
- {
- #define X prev_rnum
- /* https://en.wikipedia.org/wiki/Linear_feedback_shift_register
- * Implementation of a primitive polynomial
- */
- uint16_t new_bit = ((X >> 0) ^ (X >> 1) ^ (X >> 3) ^ (X >> 12)) & 1;
- *pbit_out = (X | (X >> 2)) & 1;
- #undef X
- return (new_bit << 15) | (prev_rnum >> 1);
- }
- #ifndef NDEBUG
- /* This is a rough translation of Jim's Intel 8741 assembler code into C
- */
- static uint16_t get_next_rnum_bit_8741(uint16_t prev_rnum, uint16_t *pbit_out)
- {
- uint8_t RNUM = prev_rnum & 0xFF; /* low-order byte */
- uint8_t RNUMp1 = prev_rnum >> 8; /* high-order byte */
- uint8_t A, C, tmp;
- #define GET_BIT(var, bit) ((var >> bit) & 1)
- #define cpl(reg) reg = reg ^ 1
- #define jnb(var, bit, label) if (!(var & (1 << bit))) goto label
- #define orl(reg, var, bit) reg |= ((var >> bit) & 1)
- #define rrc(reg) tmp = reg & 1; reg = (C << 7) | (reg >> 1); C = tmp
- /* ;This subroutine implements a 16 bit random number generator based
- * ;on the primitive polynomial:
- * ;
- * ; 1 + X + X^3 + X^12 + X^16
- * ;
- * ;The value is stored in memory as RNUM. This subroutine returns
- * ;with the low order byte of the RNUM in the accumulator and a random
- * ;bit value in the Carry (C) bit.
- * ;
- */
- C = GET_BIT(RNUM, 0); /* mov C, RNUM.0 ;get the units value of the PP */
- jnb(RNUM, 1, rand1); /* jnb RNUM.1, rand1 ;jmp if X = 0 */
- cpl(C); /* cpl C ;else compliment C (xor) */
- rand1: jnb(RNUM, 3, rand2); /* jnb RNUM.3, rand2 ;jmp if X^3 = 0 */
- cpl(C); /* cpl C ;else compliment C (xor) */
- rand2: jnb(RNUMp1, 4, rand3); /* jnb (RNUM+1).4, rand3 ;jmp if X^12 = 0 */
- cpl(C); /* cpl C ;else compliment C (xor) */
- rand3: A = RNUMp1; /* mov A, RNUM+1 ;get high byte of RNUM */
- rrc(A); /* rrc A ;and rotate down (thru accumulator) */
- RNUMp1 = A; /* mov RNUM+1, A ;save it back to memory */
- A = RNUM; /* mov A, RNUM ;get low byte of RNUM */
- rrc(A); /* rrc A ;and rotate down (thru accumulator) */
- RNUM = A; /* mov RNUM, A ;save it back to memory */
- orl(C, RNUM, 1); /* orl C, RNUM.1 ;set C only 25 percent of the time */
- /* ret ;return */
- *pbit_out = C;
- #undef GET_BIT
- #undef cpl
- #undef jnb
- #undef orl
- #undef rrc
- return RNUM | (RNUMp1 << 8);
- }
- #endif /* !NDEBUG */
- static void print_row(uint16_t x)
- {
- uint16_t m;
- int pos;
- char v[17];
- /* 0 -> LED on, 1 -> LED off */
- for (m = 1 << 15, pos = 0; m != 0; m >>= 1, pos++)
- v[pos] = (x & m) ? '-' : 'O';
- v[16] = '\0';
- puts(v);
- }
- int main(void)
- {
- uint16_t rnum = 1;
- uint16_t rows[NUM_ROWS];
- int i;
- memset(rows, 0, sizeof(rows));
- for (;;)
- {
- for (i = 0; i < NUM_ROWS; i++)
- {
- uint16_t rnum_new, bit = 0;
- rnum_new = get_next_rnum_bit(rnum, &bit);
- if (i & 4)
- rows[i] = (bit << 15) | (rows[i] >> 1);
- else
- rows[i] = (rows[i] << 1) | bit;
- #ifndef NDEBUG
- {
- uint16_t rnum_new_8741, bit_8741 = 0;
- rnum_new_8741 = get_next_rnum_bit_8741(rnum, &bit_8741);
- assert(rnum_new == rnum_new_8741);
- assert(bit == bit_8741);
- }
- #endif
- rnum = rnum_new;
- }
- /* ANSI sequence to clear terminal */
- fputs("\033[2J\033[1;1H", stdout);
- for (i = 0; i < NUM_ROWS_DISPLAYED; i++)
- print_row(rows[i & 31]);
- fflush(stdout);
- usleep(200000);
- }
- return 0;
- }
- /* EOF */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement