8-Bit Software

The BBC and Master Computer Public Domain Library

Back to 8BS Or Back to Disassembly


Page Last Altered:

AA73 RND

Submitted by Steve Fewell

Description:

If the next character after the 'RND-token' at the BASIC Text Pointer B location is not '(' then set the IWA to the Next
Random Number Seed value (from locations &0D-&10), as follows:
* Call &831E to calculate the next Random Number Seed value.
* Set X to #&0D (the start of the Random Number seed value).
* Continue to routine &AA80 to set the IWA to the Integer value starting at the location specified in X
   (that is locations &0D, &0E, &0F, &10) and exit.
[&AA3B] Increment BASIC Text Pointer B offset value (to point to the next character after the '('-character).
Call routine &96A7 to obtain the Integer value at the BASIC Text Pointer B location (putting the result in the IWA),
and then check that the next non-space character is a close bracket ')', if it isn't then issue a 'Syntax error'.

If the Integer value is negative (top bit of IWA MSB (&2D) is set) then set the Random number seed value as follows:
* Set X to #&0D
* Call routine &BDC6 to set locations X => X+3 to the IWA value (that is locations &0D-&10).
* Set location &11 (the fifth byte of the Random Number Seed value) to #&40 and exit.
Otherwise, if the IWA value is less than 256 (i.e. bytes &2D, &2C and &2B are zero) then check the IWA LSB byte
value (&2A). This determines whether the IWA value is 0 or 1 (as tested below).
If the IWA value is 0 then Return the previous Random Number Float value (between 0 and 1) as follows:
* [&AA21] Zero the FWA Sign (&2E), Exponent Overflow (&2F) and Mantissa Rounding (&35) bytes
* Set the FWA Exponent (&30) to #&80 - so that the FWA value will be between the range 0.0 to 1.0
* EOR the exponent (#&80) with &0D (to remove any top bit) and store the result as FWA Mantissa byte 4 (&34).
* EOR the FWA Mantissa Byte 4 with &0E and store the result as FWA Mantissa byte 3 (&33).
* EOR the FWA Mantissa Byte 3 with &0F and store the result as FWA Mantissa byte 2 (&32).
* EOR the FWA Mantissa Byte 2 with &10 and store the result as FWA Mantissa byte 1 (&31).
* Call routine &A854 to Normalise the FWA value & round the FWA Mantissa to 4 bytes
* Set A to #&FF (as a Floating-Point result has just been calculated) and exit.
If the IWA value is 1 then Return a Random Number Floating-Point value between 0 and 1, as follows:
* [&AA1E] Call routine &831E to calculate the next Random Number Seed value
* [&AA21] Zero the FWA Sign (&2E), Exponent Overflow (&2F) and Mantissa Rounding (&35) bytes
* Set the FWA Exponent (&30) to #&80 - so that the FWA value will be between the range 0.0 to 1.0
* EOR the exponent (#&80) with &0D (to remove any top bit) and store the result as FWA Mantissa byte 4 (&34).
* EOR the FWA Mantissa Byte 4 with &0E and store the result as FWA Mantissa byte 3 (&33).
* EOR the FWA Mantissa Byte 3 with &0F and store the result as FWA Mantissa byte 2 (&32).
* EOR the FWA Mantissa Byte 2 with &10 and store the result as FWA Mantissa byte 1 (&31).
* Call routine &A854 to Normalise the FWA value & round the FWA Mantissa to 4 bytes
* Set A to #&FF (as a Floating-Point result has just been calculated) and exit.
Otherwise, calculate a Random Integer Number between 1 and the IWA value, as follows:
* [&AA52] Call routine &8185 to convert the Integer value (in the IWA) to a Floating-Point value (in the FWA)
* Call routine &BBFA to push the FWA value to the BASIC Stack
* Call routine &AA1E to set the FWA to a Random Floating-Point value between 0.0 and 1.0 (as described above
   for RND(1)).
* Retrieve the Float Value from the BASIC Stack (and set argp (&4A, &4B) to point to the packed Floating-Point value)
* Call routine &A6CF to Multiply the Packed Floating-Point value (pointed to by argp) by the FWA value (storing
   the result in the FWA) [i.e. FWA=argp*FWA]
* Call routine &96C3 to convert the FWA value to an Integer (placing the result in the IWA)
* Now the IWA contains an Integer value between 0 and the original Integer value minus 1. This is because the Random
   Floating-Point number was between the range 0.0 to 1.0; with low FWA values (e.g. 0.0003) resulting in a zero Integer result
   and high FWA values (e.g. 0.9999) resulting in an Integer result of 1 less than the original Integer value. This is because
   the FWA value is not rounded up on conversion to Integer (the value is truncated instead, with the fractional part being lost).
* Call routine &BEEF to increment the IWA value. Now the IWA value is in the correct range (i.e. a value between 1
   and the original Integer value (that was specified between the parenthesis of the RND command).
* Exit with A = #&40 (to indicate that the current result value is an Integer in the IWA)


Disassembly for the RND routine

AA1E   032 030 131 20 1E 83 JSR &831E Calculate next Random Number Seed value
AA21 d. 100 046 64 2E STZ &2E
AA23 d/ 100 047 64 2F STZ &2F
AA25 d5 100 053 64 35 STZ &35
AA27   169 128 A9 80 LDA#&80
AA29 0 133 048 85 30 STA &30
AA2B   160 000 A0 00 LDY#&00
AA2D   162 003 A2 03 LDX#&03
AA2F Y 089 013 000 59 0D 00 EOR &000D,Y
AA32 1 149 049 95 31 STA &31,X
AA34   200 C8 INY
AA35   202 CA DEX
AA36   016 247 10 F7 BPL -9 --> &AA2F
AA38 LT 076 084 168 4C 54 A8 JMP &A854 Normalise FWA, round FWA Mantissa to 4-bytes & set A=&FF
AA3B   230 027 E6 1B INC &1B
AA3D   032 167 150 20 A7 96 JSR &96A7 Extract Integer result of expression & check for ')'
AA40 - 165 045 A5 2D LDA &2D
AA42 0% 048 037 30 25 BMI 37 --> &AA69 Set Random Number Seed value
AA44 , 005 044 05 2C ORA &2C
AA46 + 005 043 05 2B ORA &2B
AA48   208 008 D0 08 BNE 8 --> &AA52
AA4A * 165 042 A5 2A LDA &2A
AA4C   240 211 F0 D3 BEQ -45 --> &AA21 Get previous Random Floating-Point Number
AA4E   201 001 C9 01 CMP#&01
AA50   240 204 F0 CC BEQ -52 --> &AA1E Get new Random Floating-Point Number
AA52   032 133 129 20 85 81 JSR &8185 Convert Integer to Float
AA55   032 250 187 20 FA BB JSR &BBFA Push FWA to Stack
AA58   032 030 170 20 1E AA JSR &AA1E Get new Random Floating-Point Number
AA5B   032 232 187 20 E8 BB JSR &BBE8 Pop Float from Stack to argp
AA5E   032 207 166 20 CF A6 JSR &A6CF Floating-Point Multiplication (FWA=argp*FWA)
AA61   032 195 150 20 C3 96 JSR &96C3 Convert Float to Integer
AA64   032 239 190 20 EF BE JSR &BEEF Increment IWA value
AA67 ' 128 039 80 27 BRA 39 --> &AA90 Exit with A=&40
AA69   162 013 A2 0D LDX#&0D
AA6B   032 198 189 20 C6 BD JSR &BDC6 Store Integer (IWA) to zero page location
AA6E @ 169 064 A9 40 LDA#&40
AA70   133 017 85 11 STA &11
AA72 ` 096 60 RTS
AA73   164 027 A4 1B LDY &1B
AA75   177 025 B1 19 LDA (&19),Y
AA77 ( 201 040 C9 28 CMP#&28
AA79   240 192 F0 C0 BEQ -64 --> &AA3B
AA7B   032 030 131 20 1E 83 JSR &831E Calculate next Random Number Seed value
AA7E   162 013 A2 0D LDX#&0D
AA80   ...Load IWA with Integer from Zero Page Address...

 


 Back to 8BS
Or