Changeset 4f508e6 in buchla-68k for lib700/rand24.s
- Timestamp:
- 07/01/2017 02:34:46 PM (7 years ago)
- Branches:
- master
- Children:
- 08e1da1
- Parents:
- f40a309
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib700/rand24.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *rand24.s -- generate a 24 bit random number3 *Version 3 -- 1988-04-29 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------5 *Synopsis:6 *long7 *rand24()8 * 9 *Based on:10 *Knuth, Donald E.11 *The Art of Computer Programming,12 *Volume 2: Semi-Numerical Algorithms13 * 14 *Computes:15 * S = [S *C] + K16 * 17 *Where:18 *K = 119 *C = 314159262120 *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 using26 *individual bits is probably not a good idea. Using more bits makes things27 *appear more random.28 *------------------------------------------------------------------------------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 29 .text 30 * 30 31 31 .xdef _rand24 32 * 32 33 33 .xdef _rseed 34 * 35 *equates for things in the BIOS36 * 37 RCLOCK .equ $49E *LONG - 200 Hz clock38 * 39 *equates for stack offsets40 * 41 ARG1 .equ 8 *LONG / WORD - arg1 / MS bits42 ARG1L .equ 10 *WORD - arg1 LS bits43 ARG2 .equ 12 *LONG / WORD - arg2 / MS bits44 ARG2L .equ 14 *WORD - arg2 LS bits45 * 46 PART .equ -4 *LONG - partial product47 * 48 PI .equ $BB40E62D *LONG - PI as a hex value49 * 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 50 .page 51 * 52 *mult32 -- 32 bit signed multiply53 *------ ----------------------54 mult32: link a6,#-4 *link stack frames55 clr.w d2 *clear sign flags56 tst.l ARG1(a6) *check sign of 1st argument57 bge mult32a *...58 * 59 neg.l ARG1(a6) *make 1st argument positive60 addq.w #1,d2 *log its sign as negative61 * 62 mult32a: tst.l ARG2(a6) *check sign of 2nd argument63 bge mult32b *...64 * 65 neg.l ARG2(a6) *make 2nd argument positive66 addq.w #1,d2 *log its sign as negative67 * 68 mult32b: move.w ARG1L(a6),d0 *generate 1st partial product69 mulu ARG2L(a6),d0 *...70 move.l d0,PART(a6) *...71 move.w ARG1(a6),d0 *generate 2nd partial product72 mulu ARG2L(a6),d0 *...73 move.w ARG2(a6),d1 *generate 3rd partial product74 mulu ARG1L(a6),d1 *...75 add.w d1,d0 *add partial products76 add.w PART(a6),d0 *...77 move.w d0,PART(a6) *...78 move.l PART(a6),d0 *...79 btst #0,d2 *adjust sign of result80 beq mult32c *...81 * 82 neg.l d0 *...83 * 84 mult32c: unlk a6 *unlink stack frames85 rts *return86 * 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 87 .page 88 * 89 *_rand24 -- Generate a random number90 *------- ------------------------91 _rand24: link a6,#0 *Link stack frames92 tst.l _rseed *See if the seed is zero93 bne rand01 *Jump if not94 * 95 move.l RCLOCK,d0 *Pick up the 200 Hz clock96 moveq.l #16,d1 *Shift it left97 asl.l d1,d0 *...98 or.l RCLOCK,d0 *OR in current 200 Hz clock99 move.l d0,_rseed *Use that as the seed100 * 101 rand01: move.l #PI,-(a7) *Put PI on the stack102 move.l _rseed,-(a7) *... and _rseed, too103 bsr mult32 *Multiply them104 addq.l #8,a7 *Cleanup stack105 addq.l #1,d0 *Add 1 to the result106 move.l d0,_rseed *Save as new seed107 asr.l #8,d0 *Make it a 24 bit number108 and.l # $00FFFFFF,d0 *...109 unlk a6 *Unlink stack frames110 rts *Return to caller111 * 112 *------------------------------------------------------------------------------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 113 .bss 114 *------------------------------------------------------------------------------115 * 116 _rseed: .ds.l 1 *random number seed117 * 114 | ------------------------------------------------------------------------------ 115 116 _rseed: .ds.l 1 | random number seed 117 118 118 .end
Note:
See TracChangeset
for help on using the changeset viewer.