; --------------------------------------------------------------------
; GENERATE RNG FILTERS

.model tiny
.code
 org 100h
.radix 16

start:  mov     bx,0001                 ;filter = 1
seed1:  mov     ax,0001                 ;seed   = 1
        mov     cx,0                    ;count  = 0

; 8 bit pseudo-random number generator

random: mov     dx,ax                   ;copy current value to DX
        and     dx,bx                   ;extract appropriate bits
        xor     dl,dh                   ;determine parity of filtered bits
        clc                             ;clear carry flag
        jpe     shift                   ;new bit = 0
        stc                             ;new bit = 1
shift:  rcr     ax,1                    ;shift AX right, bringing in carry bit
        inc     cx                      ;increment count
        jz      disp                    ;count cannot exceed FFFFh
        cmp     ax,1                    ;check for repetition of cycle
        jne     random                  ;if not, go again

; Display filter in binary

disp:   cmp     cx,0FFFF                ;ideal filter ?
        je      disp1                   ;yes, display it
        jmp     repeat                  ;else, try again

disp1:  mov     di,offset output        ;point to output string
        mov     cx,10                   ;16 bits in filter
disp2:  rcl     bx,1                    ;rotate bit to carry
        mov     [di],byte ptr "0"       ;display 0 if bit clear
        jnb     disp3
        inc     byte ptr [di]           ;display 1 if bit set
disp3:  inc     di                      ;shift pointer
        loop    disp2                   ;repeat for 16 bits

        rcl     bx,1                    ;17th rotation restores original value
        push    bx                      ;save filter

; Convert count into ASCII string, and display

        inc     [count]                 ;increment filter count
        mov     di,offset out2          ;point past end of number string
        mov     ax,count                ;put count to accumulator
        mov     bx,10d                  ;divide by ten to convert to decimal
        mov     cl,5                    ;5 digits
digit:  mov     dx,0                    ;DX is two MSBs for 16 bit division
        div     bx                      ;divide by 10
        add     dl,"0"                  ;DX contains least significant digit
        dec     di                      ;point to next most significant digit
        mov     [di],dl                 ;put in output string
        loop    digit                   ;repeat for 5 digits

        mov     dx,offset output        ;point to output string
        mov     ah,9                    ;display string
        int     21

; Repeat for all filters

        pop     bx                      ;restore filter
repeat: inc     bx                      ;increment it twice
        inc     bx
        cmp     bx,1                    ;done all?
        je      quit                    ;yes, finish
        jmp     seed1                   ;no, try again

; Data  storage

seed    dw      0
count   dw      0000h
output  db      "0000000000000000  00000"
out2    db      13d,10d,"$"

; End of filter generation code

quit:   mov ah,4c
        int 21

end start
