HP41 MACHINE CODE RANDOM NUMBERS Mark Power 251 Equipment Required: HP41 (Any model) M-coding equipment (e.g. ZENROM + RSU) The two combined routines presented here show the speed advantage of m-code over FOCAL. The two produce a random number which is in the range 0 <= RAN < 1 and place it in the X register, observing the normal rules of the Stack Lift operation. The difference between the two routines is that RAN00 takes its seed from register 00 and RAN20 uses register 20. Both write a new seed back to the appropriate register ready for the next time. It should be noted that the technique for creating the random number is designed to be very fast, requiring a minimum of equipment and so is very 'dirty'. The routines are not designed for statistical purposes but more for use in games. As far as I can tell the results are random! DEPENDENCIES: NONE {No User Routines} ROUTINES USED: {UNLABELED} @ 0024 . TRC10 @ 19A1. LXEX @ 1229 INPUT: RAN00 & RAN20 take seed from appropriate register. May be normalised or ALPHA data. Non-normalised numbers are set to zero before calculations start. OUTPUT: Random number in the range 0 <= RAN < 1 is pushed into X & seed register. Stack lift operates as normal (same as RCL) ERRORS: If the seed register does not exist NONEXISTENT is given. ADDR HEX MNEMONIC COMMENTS ..... ---- --- -------- -------------- *395 0B0 0: *396 030 0 *397 00E N *398 001 A *399 012 R *39A 046 C=0 S&X ;Entry point for RAN00 *39B 043 JNC+08 RANC ;Jump to common part with offset 0 *39C 0B0 0: *39D 032 2 *39E 00E N *39F 001 A *3A0 012 R *3A1 130 LDI ;Entry point for RAN20 *3A2 014 HEX 014 ;Offset of 20 decimal *3A3 091 NC XQ ;Clear flag 7 and jump into OVRSTK. *3A4 000 0024 ;to find register with OFFSET & select it *3A5 2A0 SETDEC ;Decimal so we don't get hex digits *3A6 285 NC XQ ;Load digits used by PI/2, leaves *3A7 064 TRC10 {19A1} ;active pointer at nybble 12 ready for below *3A8 0EE C<>B ALL ;Get seed out of B and save constant *3A9 1EE C=C+C ALL ;Double the seed *3AA 14E A=A+C ALL ;Add it into A *3AB 12E A=A+B ALL ;Add constant to A *3AC 01E A=0 MS ;Force +ve sign *3AD 006 A=0 S&X ;Set exponent to 0. this gives *3AE 35A ?A#0 M ;a value of 0.xxxx.... below *3AF 033 JNC+06 END0 ;Jump down if mantissa is all zeroes *3B0 1A6 A=A-1 S&X ;Decrement exponent *3B1 342 ?A#0 @R ;Check that mantissa is normalised *3B2 027 JC+04 END1 ;If it is then end *3B3 3FA LSHFA M ;Otherwise shift mantissa left *3B4 3E3 JNC-04 LOOP ;Go back & decrement exponent again *3B5 00E A=0 ALL ;Zero whole word if mantissa = 000.... *3B6 0AE A<>C ALL ;Get value into C and write it back *3B7 2F0 WRITE DATA ;to the seed register which is selected still *3B8 0A5 NC GO ;Lift stack if required and put C into *3B9 04A LXEX {1229} ;the X register The David Assembler labels have been omitted from this listing but for completeness exist as below: END0 @ *3B5 END1 @ *3B6 LOOP @ *3B0 RANC @ *3A3 If there is a statistician out there who can check this routine for randomness then I'm sure it could become a new fast standard. For people who play games (who us?) this routine runs faster than a single FOCAL statement such as '1' !! Need I say more.