diff --git a/STATUS.md b/STATUS.md index 4868d425..5ee5f251 100644 --- a/STATUS.md +++ b/STATUS.md @@ -237,6 +237,7 @@ Floating point mathematical routines - not official, but well known and broadly | `$BFED` | `exp_FAC1` | NOT DONE | | | `$E043` | `poly1_FAC1` | NOT DONE | | | `$E059` | `poly2_FAC1` | NOT DONE | | +| `$E09A` | `rnd_A` | DONE | | | `$E0BE` | `rnd_generate` | DONE | | | `$E264` | `cos_FAC1` | NOT DONE | | | `$E26B` | `sin_FAC1` | NOT DONE | | diff --git a/c64/basic/board_x16/cx16_stubs.s b/c64/basic/board_x16/cx16_stubs.s new file mode 100644 index 00000000..5b64b03d --- /dev/null +++ b/c64/basic/board_x16/cx16_stubs.s @@ -0,0 +1,8 @@ +// #LAYOUT# X16 BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// Stubs for Commander X16 support + + +rnd_seed_init: + jmp rnd_generate diff --git a/c64/basic/math/e09a.interop b/c64/basic/math/e09a.interop new file mode 100644 index 00000000..5c452b05 --- /dev/null +++ b/c64/basic/math/e09a.interop @@ -0,0 +1,5 @@ +This is an important floating point math routine, see: + +- https://www.atarimagazines.com/compute/issue72/random_numbers.php + +XXX - try to find real-life example diff --git a/c64/basic/math/e09a.rnd_A.s b/c64/basic/math/e09a.rnd_A.s new file mode 100644 index 00000000..1bb428f8 --- /dev/null +++ b/c64/basic/math/e09a.rnd_A.s @@ -0,0 +1,26 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Random number generator routine +// +// Input: +// - .A (0 - reinitialize the seed with random value, $80 or above - create seed from FAC1) +// +// Output: +// - FAC1 +// +// See also: +// - https://www.atarimagazines.com/compute/issue72/random_numbers.php +// + +rnd_A: + + cmp #$00 + beq_16 rnd_seed_init + + cmp #$80 + bcc_16 rnd_generate + + jmp rnd_seed_from_FAC1 diff --git a/c64/basic/math/e0be.rnd_generate.s b/c64/basic/math/e0be.rnd_generate.s index 2bc257f7..d315cc1a 100644 --- a/c64/basic/math/e0be.rnd_generate.s +++ b/c64/basic/math/e0be.rnd_generate.s @@ -3,7 +3,7 @@ // #LAYOUT# * * #IGNORE // -// A fast random generator, idea from: +// A fast pseudorandom generator, modified idea from: // - https://codebase64.org/doku.php?id=base:32bit_galois_lfsr // // Output: @@ -15,8 +15,6 @@ rnd_generate: - // Generate new 4-byte random number - asl RNDX+1 rol RNDX+2 rol RNDX+3 @@ -27,12 +25,15 @@ rnd_generate: lda RNDX+1 eor #$B7 sta RNDX+1 + lda RNDX+2 eor #$1D sta RNDX+2 + lda RNDX+3 eor #$C1 sta RNDX+3 + lda RNDX+4 eor #$04 sta RNDX+4 @@ -41,23 +42,32 @@ rnd_generate: rnd_generate_copy: - // Copy the number to FAC1, order changed on purpose + // Copy the generated number to FAC1, mangle it a little lda RNDX+3 + eor #$62 sta FAC1_mantissa+0 + lda RNDX+1 + eor #$4E sta FAC1_mantissa+1 - lda RNDX+2 - sta FAC1_mantissa+2 + lda RNDX+4 + eor #$97 + sta FAC1_mantissa+2 + + lda RNDX+2 sta FAC1_mantissa+3 - + + // FALLTROUGH + +rnd_generate_finalize: + lda #$00 - sta FACOV sta FAC1_sign lda #$80 + sta FACOV // just to prevent 0 after normalization sta FAC1_exponent - sta RNDX+0 // in case someone tries to use the float directly jmp normal_FAC1 diff --git a/c64/basic/math/rnd_seed_from_FAC1.s b/c64/basic/math/rnd_seed_from_FAC1.s new file mode 100644 index 00000000..0a288ca2 --- /dev/null +++ b/c64/basic/math/rnd_seed_from_FAC1.s @@ -0,0 +1,27 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Initialize random seed using values from FAC1, +// afterwards generate random number in FAC1 +// + +rnd_seed_from_FAC1: + + lda FAC1_mantissa+0 + sta RNDX+4 + + eor FAC1_mantissa+1 + sta RNDX+3 + + eor FAC1_mantissa+2 + sta RNDX+2 + + eor FAC1_mantissa+3 + sta RNDX+1 + + eor FAC1_exponent + sta RNDX+0 + + jmp rnd_generate diff --git a/c64/basic/math/rnd_seed_init.s b/c64/basic/math/rnd_seed_init.s new file mode 100644 index 00000000..56f0a13c --- /dev/null +++ b/c64/basic/math/rnd_seed_init.s @@ -0,0 +1,33 @@ +// #LAYOUT# STD * #TAKE +// #LAYOUT# X16 * #IGNORE +// #LAYOUT# * BASIC_0 #TAKE +// #LAYOUT# * * #IGNORE + +// +// Initialize random seed, afterwards generate random number in FAC1, +// try to gather as much entropy from different sources as possible +// + +rnd_seed_init: + + eor CIA1_TIMALO // timer used for IRQ generation, use potential entropy from .A + sta RNDX+3 + + txa // .X might contain some entropy + eor VIC_RASTER // lowest 8 bits of current raster line + sta RNDX+1 + + tya // .Y might contain some entropy + eor CIA1_TIMAHI + sta RNDX+4 + + lda TIME+0 // byte from jiffy counter might be useful too + eor SID_RANDOM // not sure if SID set correctly, but it will not hurt +#if CONFIG_MB_MEGA_65 + eor VIC_XPOS // not sure if VIC-IV visible, but it will not hurt +#endif + sta RNDX+2 + + // RNDX+0 will be overwritten by generator + + jmp rnd_generate