Path: news.weeg.uiowa.edu!news.uiowa.edu!hobbes.physics.uiowa.edu!math.ohio-state.edu!howland.reston.ans.net!gatech!news-feed-1.peachnet.edu!paperboy.wellfleet.com!noc.near.net!news.delphi.com!usenet From: John Holmes Newsgroups: comp.sys.apple2.programmer Subject: Re: Algorithms anyone? Date: Sun, 8 May 94 09:33:22 -0500 Organization: Delphi (info@delphi.com email, 800-695-4005 voice) Lines: 169 Message-ID: References: <2po99i$c8u@news.ysu.edu> NNTP-Posting-Host: bos1d.delphi.com X-To: Eric S. Ford I have a chunk of source for random numbers that follows..hoope it is of some help to you. ******************************** * * * USRND * * * * by * * Tom Hare, John Russ, Gary * * Faulkner, and David Sparks * * * * A random-number generator * * for 48k ROM or L/C Applesoft * * * * Call-A.P.P.L.E. : Jan. 1983 * * * ******************************** * * * The following machine language program is * relocatable, but is shown here assembled * to reside at $300. It is "hooked" into the * Applesoft USR function when it is BRUN. * The calling format is (e.g.) X = USR (A). * If A is 1 the value will be a real number * between 0 and 1 (the usual form for random * numbers). If A is a positive number greater * than 1, an integer 0...(A-1) is returned. * Arguments between 0 and 1 always return 0, and * arguments < 0 are rejected (error message). * RND (0) returns the previous value. * * The alogrithm for the random number generator * starts with a seed value S and upon each * call calculates a new seed value * S' = (8192 * S) MOD 67099547. * Each random number is taken as the seed * value divided by 67099547. This method * will pass even quite exacting tests for * "Randomness", and is strongly recommended * as an alternative to the Applesoft RND function. * The original alogrithm, which is used in some * large computer programs, was introduced to * us by Gary Faulkner, Dept. of Physical and * Mathematical Sciences, North Carolina State * University. It was first programmed in BASIC * and subsequently in machine language by Tom * Hare, School of Engineering, NCSU. His program * was refined further by John Russ (Engineering * Research, NCSU) and David Sparks (Call-A.P.P.L.E. * staff writer). The accompanying article describes * the method and several tests of this and other * random number generators. * ORG $2F4 ;A convenient location * LDA #$4C ;"JMP" STA $0A ;The USR vector LDA #RANDOM ;Hi byte too STA $0C LDY #4 ;Use the 4 bytes from INITR LDA $C9,Y ;Applesoft's RND seed AND MASK-1,Y ;to create our seed STA BYT1-1,Y ;(which may not exceed DEY ;the magic 67099547) * NOTE: this means that the random number * generator can be seeded by RND (-N) and CALL 768 BNE INITR RTS * RANDOM LDA $9D ;check for 0 BEQ DIVIDE ;return last one LDA $A2 ;check positive BPL SAVE JMP $E199 ;"ILLEGAL QUANTITY" * SAVE LDY #>RANGE ;save the argument LDX #mem. subr. LDX #$F3 ;-13 into counter SUBLOOP ASL BYT1 ;shift the seed 13 ROL BYT2 ;times to multiply ROL BYT3 ;by 8192 ROL BYT4 SEC ;and try to subtract LDA BYT1 ;67099547 to perform SBC #155 ;the MOD function PHA ;NOTE- the values LDA BYT2 ;shown are the floating SBC #219 ;point representation PHA ;of the number. The LDA BYT3 ;difference is saved SBC #255 ;on the stack for now PHA LDA BYT4 SBC #3 PHA BCC LESS ;branch if < 67099547 PLA ;otherwise replace STA BYT4 ;the seed value PLA ;with the MOD result STA BYT3 ;which we cleverly PLA ;saved on the stack STA BYT2 ;while testing PLA STA BYT1 BCS INCR ;forced branch LESS PLA ;gotta clean up PLA ;the stack! PLA PLA INCR INX ;increment counter BNE SUBLOOP ;and keep shifting DIVIDE LDA #3 ;place 67099547 STA $9E ;into FAC LDA #255 STA $9F LDA #219 STA $A0 LDA #155 STA $A1 LDA #0 STA $A2 STA $AA STA $AB LDA #$81 STA $A5 STA $9D LDA BYT4 ;and move seed value STA $A6 ;to auxiliary FAC LDA BYT3 ;before multiplying STA $A7 LDA BYT2 STA $A8 LDA BYT1 STA $A9 LDA #$9D JSR $E82E ;Normalize FAC JSR $EA69 ;Divide AUX/FAC * These Applesoft calls leave the random number * in the floating point accumulator (FAC) LDA RANGE ;now check the user's SEC ;RANGE argument SBC #$81 ;is it a 1 (exactly) ORA RANGE+1 ORA RANGE+2 ORA RANGE+3 BNE SCALE ;NO RTS ;YES (return with fraction) SCALE LDY #>RANGE ;load address to use LDA #