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