random16: cycle-invariant version

man this was a pain
This commit is contained in:
Vince Weaver 2018-09-10 14:05:45 -04:00
parent 1dbc60d0c1
commit 9a60e6fe40

View File

@ -1,9 +1,9 @@
; 16-bit 6502 Random Number Generator ; 16-bit 6502 Random Number Generator (cycle-invariant version)
; Linear feedback shift register PRNG by White Flame ; Linear feedback shift register PRNG by White Flame
; http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng ; http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng
; The Apple II KEYIN routine increments this field ; The Apple II KEYIN routine increments SEEDL:SEEDH
; while waiting for keypress ; while waiting for keypress
SEEDL = $4E SEEDL = $4E
@ -15,46 +15,97 @@ XOR_MAGIC = $7657 ; "vW"
; random16 ; random16
;============================= ;=============================
; takes: ; takes:
; not 0, cc = 5+ = 27 ; not 0, cc = 6(r16)+12(lnz)+4(nop)+ 18(neo) = 40
; not 0, cs = 5+12+19 = 36 ; not 0, cs = 6(r16)+15(lnz)+19(deo) = 40
; $0000 = 5+7+19 = 31
; $8000 = 5+6+14 = 25 ; $0000 = 6(r16)+ 6(loz)+ 9nops+ 19(deo) = 40
; $XX00 = 5+6+7+19 = 37 ; $8000 = 6(r16)+ 6(loz)+ 4(ceo) + 6nops+ 18(neo) = 40
; $XX00 cc = 6(r16)+ 6(loz)+ 4(ceo) + 2(cep) 4nops+ +18(neo) = 40
; $XX00 cs = 6(r16)+ 6(loz)+ 4(ceo) + 5(cep) +19(deo) = 40
random16: random16:
lda SEEDL ; 3 lda SEEDL ; 3
beq lowZero ; $0000 and $8000 are special values ; 2 beq low_zero ; $0000 and $8000 are special values ; 3
;==========
; 6
lownz:
; -1
asl SEEDL ; Do a normal shift ; 5 asl SEEDL ; Do a normal shift ; 5
lda SEEDH ; 3 lda SEEDH ; 3
rol ; 2 rol ; 2
bcc noEor ; 2 bcc four_cycle_no_eor ; 3
;==========
; 12
bcs do_eor ; 3
doEor: ;===================================================================
do_eor:
; high byte is in A ; high byte is in A
eor #>XOR_MAGIC ; 2 eor #>XOR_MAGIC ; 2
sta SEEDH ; 3 sta SEEDH ; 3
lda SEEDL ; 3 lda SEEDL ; 3
eor #<XOR_MAGIC ; 2 eor #<XOR_MAGIC ; 2
sta SEEDL ; 3 sta SEEDL ; 3
eor_rts:
rts ; 6 rts ; 6
;===========
; 19
lowZero: ;=========================================================================
; 1
six_cycles_no_eor:
nop ; 2
four_cycle_no_eor:
nop ; 2
nop ; 2
no_eor:
nop ; 2
nop ; 2
nop ; 2
sta SEEDH ; 3
jmp eor_rts ; 3+6
;===========
; 18
;======================================================================
;======================================================================
nine_cycle_do_eor:
nop ; 2
nop ; 2
nop ; 2
jmp do_eor ; 3
low_zero:
lda SEEDH ; 3 lda SEEDH ; 3
beq doEor ; High byte is also zero ; 3 beq nine_cycle_do_eor ; High byte is also zero ; 3
; so apply the EOR ; so apply the EOR
;============
; 6
ceo:
; -1 ; -1
; wasn't zero, check for $8000 ; wasn't zero, check for $8000
asl ; 2 asl ; 2
beq noEor ; if $00 is left after the shift ; 2 beq six_cycles_no_eor ; if $00 is left after the shift; 3
; then it was $80 ; then it was $80
bcs doEor ; else, do the EOR based on the carry ; 3 ;===========
; 4
; else, do the EOR based on the carry
cep:
; -1
bcc four_cycle_no_eor ; 3
;============
; 2
bcs do_eor ; 2+3 = 5
noEor:
; 1
sta SEEDH ; 3
rts ; 6