现在已经很晚了,但是根据要求,您也可以滚动自己的 PRNG。一些算法很容易实现,例如,我将在这里使用参数展示一个 32 位xorshift[3,25,24]
实现(因为这使得两个移位使用很少的代码)。返回的随机数有 16 位:
rnd_seed:
sta $22 ; store pointer to PRNG state
stx $23
lda #$00 ; initialize with 0
ldy #$03
rs_clrloop: sta ($22),y
dey
bne rs_clrloop
lda $d012 ; except for LSB, use current raster
bne seed_ok
lda #$7f ; or a fixed value if 0
seed_ok: sta ($22),y
rts
rnd:
sta $22 ; store pointer to PRNG state
stx $23
ldy #$03
r_cpyloop: lda ($22),y ; copy to ZP $fb - $fe
sta $fb,y
dey
bpl r_cpyloop
ldy #$03 ; and shift left 3 bits
r_shiftloop: asl $fb
rol $fc
rol $fd
rol $fe
dey
bpl r_shiftloop
ldy #$03
r_xorloop: lda ($22),y ; xor with original state
eor $fb,y
sta ($22),y
dey
bpl r_xorloop
ldy #$03
lda ($22),y
lsr a ; MSB >> 1 gives ">> 25"
ldy #$00
eor ($22),y ; xor with original state
sta ($22),y
ldy #$03 ; this is also value for "<< 24"
eor ($22),y ; so xor with MSB
sta ($22),y
tax ; use the two "higher" bytes as result ...
dey
lda ($22),y ; ... in A/X
rts
使用示例:
main:
lda init
bne noinit
lda #<prng
ldx #>prng
inc init
jsr rnd_seed
noinit: lda #<prng
ldx #>prng
jsr rnd
jmp $bdcd ; C64 BASIC routine output 16bit int in A/X
init: .byte $00
prng: .res 4 ; 32bit PRNG state