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
|
---|