dos33fsprogs/fireworks/random16.s

120 lines
2.5 KiB
ArmAsm
Raw Normal View History

; 16-bit 6502 Random Number Generator (cycle-invariant version)
2018-09-05 19:04:31 +00:00
; 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
2018-09-05 19:04:31 +00:00
; while waiting for keypress
SEEDL = $4E
SEEDH = $4F
XOR_MAGIC = $7657 ; "vW"
2018-09-06 05:09:23 +00:00
;=============================
; random16
;=============================
; takes:
2018-09-10 19:13:34 +00:00
; not 0, cs = 6(r16)+12(lnz)+5(nop)+ 19(deo) = 42
; not 0, cc = 6(r16)+14(lnz)+2(nop)+ 20(neo) = 42
2018-09-10 19:13:34 +00:00
; $0000 = 6(r16)+ 6(loz)+11nops+ 19(deo) = 42
; $8000 = 6(r16)+ 6(loz)+ 4(ceo) + 6nops+ 20(neo) = 42
2018-09-10 19:13:34 +00:00
; $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*
2018-09-05 19:04:31 +00:00
random16:
2018-09-06 05:09:23 +00:00
lda SEEDL ; 3
beq low_zero ; $0000 and $8000 are special values ; 3
;==========
; 6
lownz:
; -1
2018-09-06 05:09:23 +00:00
asl SEEDL ; Do a normal shift ; 5
lda SEEDH ; 3
rol ; 2
2018-09-10 19:13:34 +00:00
bcs five_cycle_do_eor ; 3
;===========
; 12
2018-09-10 19:13:34 +00:00
bcc two_cycle_no_eor ; 3
;==========
; 12+3-1 = 14
2018-09-05 19:04:31 +00:00
;===================================================================
2018-09-05 19:04:31 +00:00
2018-09-10 19:13:34 +00:00
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
2018-09-05 19:04:31 +00:00
2018-09-06 05:09:23 +00:00
eor #>XOR_MAGIC ; 2
sta SEEDH ; 3
lda SEEDL ; 3
eor #<XOR_MAGIC ; 2
sta SEEDL ; 3
eor_rts:
2018-09-06 05:09:23 +00:00
rts ; 6
;===========
; 19
;=========================================================================
six_cycles_no_eor:
nop ; 2
four_cycle_no_eor:
nop ; 2
2018-09-10 19:13:34 +00:00
two_cycle_no_eor:
nop ; 2
no_eor:
nop ; 2
nop ; 2
nop ; 2
2018-09-10 19:13:34 +00:00
nop ; 2
sta SEEDH ; 3
jmp eor_rts ; 3+6
;===========
2018-09-10 19:13:34 +00:00
; 20
;======================================================================
;======================================================================
2018-09-06 05:09:23 +00:00
low_zero:
2018-09-06 05:09:23 +00:00
lda SEEDH ; 3
2018-09-10 19:13:34 +00:00
beq eleven_cycle_do_eor ; High byte is also zero ; 3
; so apply the EOR
;============
; 6
ceo:
2018-09-06 05:09:23 +00:00
; -1
2018-09-05 19:04:31 +00:00
; wasn't zero, check for $8000
2018-09-06 05:09:23 +00:00
asl ; 2
beq six_cycles_no_eor ; if $00 is left after the shift; 3
; then it was $80
;===========
; 4
; else, do the EOR based on the carry
cep:
; -1
bcc four_cycle_no_eor ; 3
;============
; 2
2018-09-10 19:13:34 +00:00
bcs three_cycle_do_eor ; 2+3-1 = 4
2018-09-05 19:04:31 +00:00