[4f508e6] | 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:
|
---|
[84c0125] | 15 | | S = [S * C] + K
|
---|
[4f508e6] | 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 | | ------------------------------------------------------------------------------
|
---|
[f40a309] | 29 | .text
|
---|
[4f508e6] | 30 |
|
---|
[8325447] | 31 | .xdef rand24
|
---|
[4f508e6] | 32 |
|
---|
[f40a309] | 33 | .xdef _rseed
|
---|
[4f508e6] | 34 |
|
---|
| 35 | | equates for things in the BIOS
|
---|
| 36 |
|
---|
| 37 | RCLOCK = 0x49E | LONG - 200 Hz clock
|
---|
| 38 |
|
---|
| 39 | | equates for stack offsets
|
---|
| 40 |
|
---|
| 41 | ARG1 = 8 | LONG / WORD - arg1 / MS bits
|
---|
| 42 | ARG1L = 10 | WORD - arg1 LS bits
|
---|
| 43 | ARG2 = 12 | LONG / WORD - arg2 / MS bits
|
---|
| 44 | ARG2L = 14 | WORD - arg2 LS bits
|
---|
| 45 |
|
---|
| 46 | PART = -4 | LONG - partial product
|
---|
| 47 |
|
---|
| 48 | PI = 0xBB40E62D | LONG - PI as a hex value
|
---|
| 49 |
|
---|
[f40a309] | 50 | .page
|
---|
[4f508e6] | 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 |
|
---|
[f40a309] | 87 | .page
|
---|
[4f508e6] | 88 |
|
---|
[8325447] | 89 | | rand24 -- Generate a random number
|
---|
| 90 | | ------ ------------------------
|
---|
| 91 | rand24: link a6,#0 | Link stack frames
|
---|
[4f508e6] | 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 #0x00FFFFFF,d0 | ...
|
---|
| 109 | unlk a6 | Unlink stack frames
|
---|
| 110 | rts | Return to caller
|
---|
| 111 |
|
---|
| 112 | | ------------------------------------------------------------------------------
|
---|
[f40a309] | 113 | .bss
|
---|
[4f508e6] | 114 | | ------------------------------------------------------------------------------
|
---|
| 115 |
|
---|
| 116 | _rseed: .ds.l 1 | random number seed
|
---|
| 117 |
|
---|
[f40a309] | 118 | .end
|
---|