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 = 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 |
|
---|
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 #0x00FFFFFF,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
|
---|