[3ae31e9] | 1 | * ------------------------------------------------------------------------------
|
---|
| 2 | * rand24.s -- generate a 24 bit random number
|
---|
| 3 | * Version 3 -- 1988-04-29 -- D.N. Lynx Crowe
|
---|
| 4 | * ------------------------------------------------------------------------------
|
---|
| 5 | * Synopsis:
|
---|
| 6 | * long
|
---|
| 7 | * rand24()
|
---|
| 8 | *
|
---|
| 9 | * Based on:
|
---|
| 10 | * Knuth, Donald E.
|
---|
| 11 | * The Art of Computer Programming,
|
---|
| 12 | * Volume 2: Semi-Numerical Algorithms
|
---|
| 13 | *
|
---|
| 14 | * Computes:
|
---|
| 15 | * S = [S * C] + K
|
---|
| 16 | *
|
---|
| 17 | * Where:
|
---|
| 18 | * K = 1
|
---|
| 19 | * C = 3141592621
|
---|
| 20 | * S = the seed (if zero, it gets set from the 200 Hz clock)
|
---|
| 21 | *
|
---|
| 22 | * Returns:
|
---|
| 23 | * S >> 8 (a 24 bit pseudo-random number)
|
---|
| 24 | *
|
---|
| 25 | * Note: this function has an LSB with an exactly 50% distribution, so using
|
---|
| 26 | * individual bits is probably not a good idea. Using more bits makes things
|
---|
| 27 | * appear more random.
|
---|
| 28 | * ------------------------------------------------------------------------------
|
---|
| 29 | .text
|
---|
| 30 | *
|
---|
| 31 | .xdef _rand24
|
---|
| 32 | *
|
---|
| 33 | .xdef _rseed
|
---|
| 34 | *
|
---|
| 35 | * equates for things in the BIOS
|
---|
| 36 | *
|
---|
| 37 | RCLOCK .equ $49E * LONG - 200 Hz clock
|
---|
| 38 | *
|
---|
| 39 | * equates for stack offsets
|
---|
| 40 | *
|
---|
| 41 | ARG1 .equ 8 * LONG / WORD - arg1 / MS bits
|
---|
| 42 | ARG1L .equ 10 * WORD - arg1 LS bits
|
---|
| 43 | ARG2 .equ 12 * LONG / WORD - arg2 / MS bits
|
---|
| 44 | ARG2L .equ 14 * WORD - arg2 LS bits
|
---|
| 45 | *
|
---|
| 46 | PART .equ -4 * LONG - partial product
|
---|
| 47 | *
|
---|
| 48 | PI .equ $BB40E62D * LONG - PI as a hex value
|
---|
| 49 | *
|
---|
| 50 | .page
|
---|
| 51 | *
|
---|
| 52 | * mult32 -- 32 bit signed multiply
|
---|
| 53 | * ------ ----------------------
|
---|
| 54 | mult32: link a6,#-4 * link stack frames
|
---|
| 55 | clr.w d2 * clear sign flags
|
---|
| 56 | tst.l ARG1(a6) * check sign of 1st argument
|
---|
| 57 | bge mult32a * ...
|
---|
| 58 | *
|
---|
| 59 | neg.l ARG1(a6) * make 1st argument positive
|
---|
| 60 | addq.w #1,d2 * log its sign as negative
|
---|
| 61 | *
|
---|
| 62 | mult32a: tst.l ARG2(a6) * check sign of 2nd argument
|
---|
| 63 | bge mult32b * ...
|
---|
| 64 | *
|
---|
| 65 | neg.l ARG2(a6) * make 2nd argument positive
|
---|
| 66 | addq.w #1,d2 * log its sign as negative
|
---|
| 67 | *
|
---|
| 68 | mult32b: move.w ARG1L(a6),d0 * generate 1st partial product
|
---|
| 69 | mulu ARG2L(a6),d0 * ...
|
---|
| 70 | move.l d0,PART(a6) * ...
|
---|
| 71 | move.w ARG1(a6),d0 * generate 2nd partial product
|
---|
| 72 | mulu ARG2L(a6),d0 * ...
|
---|
| 73 | move.w ARG2(a6),d1 * generate 3rd partial product
|
---|
| 74 | mulu ARG1L(a6),d1 * ...
|
---|
| 75 | add.w d1,d0 * add partial products
|
---|
| 76 | add.w PART(a6),d0 * ...
|
---|
| 77 | move.w d0,PART(a6) * ...
|
---|
| 78 | move.l PART(a6),d0 * ...
|
---|
| 79 | btst #0,d2 * adjust sign of result
|
---|
| 80 | beq mult32c * ...
|
---|
| 81 | *
|
---|
| 82 | neg.l d0 * ...
|
---|
| 83 | *
|
---|
| 84 | mult32c: unlk a6 * unlink stack frames
|
---|
| 85 | rts * return
|
---|
| 86 | *
|
---|
| 87 | .page
|
---|
| 88 | *
|
---|
| 89 | * _rand24 -- Generate a random number
|
---|
| 90 | * ------- ------------------------
|
---|
| 91 | _rand24: link a6,#0 * Link stack frames
|
---|
| 92 | tst.l _rseed * See if the seed is zero
|
---|
| 93 | bne rand01 * Jump if not
|
---|
| 94 | *
|
---|
| 95 | move.l RCLOCK,d0 * Pick up the 200 Hz clock
|
---|
| 96 | moveq.l #16,d1 * Shift it left
|
---|
| 97 | asl.l d1,d0 * ...
|
---|
| 98 | or.l RCLOCK,d0 * OR in current 200 Hz clock
|
---|
| 99 | move.l d0,_rseed * Use that as the seed
|
---|
| 100 | *
|
---|
| 101 | rand01: move.l #PI,-(a7) * Put PI on the stack
|
---|
| 102 | move.l _rseed,-(a7) * ... and _rseed, too
|
---|
| 103 | bsr mult32 * Multiply them
|
---|
| 104 | addq.l #8,a7 * Cleanup stack
|
---|
| 105 | addq.l #1,d0 * Add 1 to the result
|
---|
| 106 | move.l d0,_rseed * Save as new seed
|
---|
| 107 | asr.l #8,d0 * Make it a 24 bit number
|
---|
| 108 | and.l #$00FFFFFF,d0 * ...
|
---|
| 109 | unlk a6 * Unlink stack frames
|
---|
| 110 | rts * Return to caller
|
---|
| 111 | *
|
---|
| 112 | * ------------------------------------------------------------------------------
|
---|
| 113 | .bss
|
---|
| 114 | * ------------------------------------------------------------------------------
|
---|
| 115 | *
|
---|
| 116 | _rseed: .ds.l 1 * random number seed
|
---|
| 117 | *
|
---|
| 118 | .end
|
---|