All pastes #488421 Raw Edit

Miscellany

public text v1 · immutable
·published 2007-05-15 00:12 UTC
rendered paste body
;=====================================================================
; Random Number Subroutines Implementation by: R.F. Genovese, Ph.D.
;                    TEKNOMETRIKA
;                    L-15, S-123
;                    11160 Veirs Mill Road
;                    Wheaton, MD 20902
;=====================================================================
;we used tasm /ml /w
;---------------------------------------------------------------------
; void _seed_ran(void)
; unsigned int _get_ran(unsigned char bitsize)
;---------------------------------------------------------------------
        DATASEG
        PUBLIC  _r_seed
_r_seed DD      55aaaaaah               ;31 bit shift register
        CODESEG
;---------------------------------------------------------------------
; void _seed_ran(void)
; seeds the 31 bit shift register used by the pseudorandom generator
; from  BIOS ticks counter at 40h:6ch
;---------------------------------------------------------------------
PROC    _seed_ran
        mov     ax,40h                  ;BIOS segment
        mov     es,ax
        mov     ax,[es:6ch]             ;get ticks
        mov     [WORD LOW _r_seed],ax   ;into lsw shift register
; we rather cheaply toggle ax and stick it in the high word
        not     ax
        mov     [WORD HIGH _r_seed],ax  ;into msw shift register
        ret                             ;that's it
ENDP    _seed_ran
;---------------------------------------------------------------------
; unsigned int _get_ran(unsigned char bitsize)
; returns a pseudorandom number as an unsigned integer with
; bitsize number of bits.  Maximum value of bitsize is 16.  Larger
; values will be truncated to 16 bits (i.e. unsigned int size) as
; will a bitsize=0.
;---------------------------------------------------------------------
GR_BITSIZE  EQU   4
GR_RESULT   EQU   6
PROC    _get_ran
        push    bp
        mov     bp,sp
        push    cx
        push    bx
        push    ax
;first get and check bitsize from caller
        mov     cl,[bp + GR_BITSIZE]
        xor     ch,ch
        jcxz    @@truncate
        cmp     cx,10h
        jle     @@size_ok
@@truncate:
        mov     cx,10h                  ;force 16 bit size
@@size_ok:
        xor     ax,ax                   ;initalize return value
@@gen_num:
;generate bitsize pseudorandom bits into ax by the result of
;(bit three xor bit six) of the high byte of the shift register
;the result is shifted into the cf and then into ax.
        mov     bx,[WORD HIGH _r_seed]
        and     bh,048h                 ;08h or 40h is result=1 else 0
        cmp     bh,08h
        jz      xor1
        cmp     bh,40h
        jz      xor1
        clc                             ;xor result=0 so clear carry
        jmp     short shift_bits
xor1:
        stc                             ;xor result=1 so set carry
;rotate the shift register with the cf becoming the lsb.
shift_bits:
        rcl     [WORD LOW  _r_seed],1
        rcl     [WORD HIGH _r_seed],1
;rotate cf into our pseudorandom number in ax.
        rcl     ax,1
        loop    @@gen_num               ;get all of the bits
        mov     [bp + GR_RESULT], ax
        pop     cx
        pop     bx
        pop     ax
        pop     bp                      ;clean up and pass the
        ret                             ;number in ax to C
ENDP    _get_ran
;webedone