diff --git a/xmas_2019/random16.s b/xmas_2019/random16.s new file mode 100644 index 00000000..44b45a79 --- /dev/null +++ b/xmas_2019/random16.s @@ -0,0 +1,119 @@ +; 16-bit 6502 Random Number Generator (cycle-invariant version) + +; Linear feedback shift register PRNG by White Flame +; http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng + +; The Apple II KEYIN routine increments SEEDL:SEEDH +; while waiting for keypress + +;SEEDL = $4E +;SEEDH = $4F + +XOR_MAGIC = $7657 ; "vW" + + ;============================= + ; random16 + ;============================= + ; takes: + ; not 0, cs = 6(r16)+12(lnz)+5(nop)+ 19(deo) = 42 + ; not 0, cc = 6(r16)+14(lnz)+2(nop)+ 20(neo) = 42 + + ; $0000 = 6(r16)+ 6(loz)+11nops+ 19(deo) = 42 + ; $8000 = 6(r16)+ 6(loz)+ 4(ceo) + 6nops+ 20(neo) = 42 + + ; $XX00 cc = 6(r16)+ 6(loz)+4(ceo)+2(cep) +4nops+ 20(neo) = 42 + ; $XX00 cs = 6(r16)+ 6(loz)+4(ceo)+4(cep) +3nops+ 19(deo) = 42* +random16: + + lda SEEDL ; 3 + beq low_zero ; $0000 and $8000 are special values ; 3 + ;========== + ; 6 +lownz: + ; -1 + asl SEEDL ; Do a normal shift ; 5 + lda SEEDH ; 3 + rol ; 2 + bcs five_cycle_do_eor ; 3 + ;=========== + ; 12 + + bcc two_cycle_no_eor ; 3 + ;========== + ; 12+3-1 = 14 + + +;=================================================================== + +eleven_cycle_do_eor: + nop ; 2 + nop ; 2 + nop ; 2 +five_cycle_do_eor: + nop ; 2 +three_cycle_do_eor: + sta SEEDH ; nop ; 3 + +do_eor: + ; high byte is in A + + eor #>XOR_MAGIC ; 2 + sta SEEDH ; 3 + lda SEEDL ; 3 + eor #$2000,>$2080,>$2100,>$2180,>$2200,>$2280,>$2300,>$2380 +.byte >$2028,>$20A8,>$2128,>$21A8,>$2228,>$22A8,>$2328,>$23A8 +.byte >$2050,>$20D0,>$2150,>$21D0,>$2250,>$22D0,>$2350,>$23D0 + +hgr_offsets_l: +.byte <$2000,<$2080,<$2100,<$2180,<$2200,<$2280,<$2300,<$2380 +.byte <$2028,<$20A8,<$2128,<$21A8,<$2228,<$22A8,<$2328,<$23A8 +.byte <$2050,<$20D0,<$2150,<$21D0,<$2250,<$22D0,<$2350,<$23D0 + + +.include "random16.s"