;********************************************************************* ;* RNDINIT, RNDPREV, RNDNEXT ;* Generate pseudo-randoms using David Crane's Pitfall LFSR ;* Entry Values ;* RANDOM contains the current LFSR state ;* Exit Values ;* RANDOM' contains the PREV or NEXT state based on call ;* A' contains the PREV or NEXT state based on call ;* Control Register Modifications ;* PC, A, CC.C, CC.N, CC.Z, CC.V ;* Subroutines Called ;* None ;* Thanks to: ;* David Crane for Pitfall ;* Thomas Jentzsch for the 6502 Pitfall disassembly ;* Sam Trenholme for A 4096-byte jungle web log series ;********************************************************************* RANDOM: rmb 1 ; 8-bit pseudo-random BLKCNT equ $94 ; BASIC ROM zero page cursor blink frames RNDINIT: ; seed the shift register lda #$c4 ; all hail Pitfall! adda BLKCNT ; use cursor blink to seed 0-11 more sta RANDOM ; we're going to start with this seed rts ; seeded - now wait for use RNDPREV: ; random' = random >> 1 | (bit4^bit5^bit6^bit1) * $80 lda RANDOM ; A' = RANDOM asla ; C = A >> 7; A << = 1 eora RANDOM ; A' ^= RANDOM asla ; C = A >> 7; A << = 1 eora RANDOM ; A' ^= RANDOM asla ; C = A >> 7; A << = 1 asla ; C = A >> 7; A << = 1 rola ; T = A; A << = 1; A |= (C & 1); C = T >> 7 eora RANDOM ; A ^= RANDOM lsra ; C = A & 1; A >> = 1 ror RANDOM ; T = RANDOM; RANDOM >> = 1; RANDOM |= (C << 7); C = T & 1 lda RANDOM ; load A' with final result for return rts RNDNEXT: ; random' = random << 1 | (bit3^bit4^bit5^bit7) lda RANDOM ; A' = RANDOM asla ; C = A >> 7; A << = 1 eora RANDOM ; A' ^= RANDOM asla ; C = A >> 7; A << = 1 eora RANDOM ; A' ^= RANDOM asla ; C = A >> 7; A << = 1 asla ; C = A >> 7; A << = 1 eora RANDOM ; A' ^= RANDOM asla ; C = A >> 7; A << = 1 rol RANDOM ; T = RANDOM; RANDOM << = 1; RANDOM |= (C & 1); C = T >> 7 lda RANDOM ; load A' with final result for return rts ;********************************************************************* ;* RND2 - generate a randomized 0 or 1 return in A for PLACECARGO X ;********************************************************************* RND2: jsr RNDNEXT ; get a random number sta RANDOM ; save back our next seed bmi RND2R1 ; 128-255? return a 1 RND2R0: clra ; we're placing cargo in original column rts ; and return this result to PLACECARGO RND2R1: lda #1 ; we're placing cargo 1 column right rts ; and return this result to PLACECARGO ;********************************************************************* ;* RND3 - generate a randomized 0, 1, or 2 return in B for PLACECARGO Y ;********************************************************************* RND3: jsr RNDNEXT ; get a random number sta RANDOM ; save back our next seed cmpa #85 ; result in lower third of range? blo RND3R0 ; 0-84? return a 0 cmpa #171 ; result in middle third of range? blo RND3R1 ; 85-170? return a 1 bra RND3R2 ; 171+ return a 2 RND3R0: ldb #1 ; we're placing cargo in original row rts ; and return this result to PLACECARGO RND3R1: ldb #2 ; we're placing cargo 1 row down rts ; and return this result to PLACECARGO RND3R2: ldb #3 ; we're placing cargo 2 rows down rts ; and return this result to PLACECARGO ;********************************************************************* ;* Test code ;********************************************************************* IFDEF INCLTEST RNDBLK: rmb 256 ; lets save a block of 256 rands RNDTEST: lda #$c4 ; start with Pitfall default world sta RANDOM ; save it to start with sta RNDBLK ; save it at start of bulk rnd block ldx #RNDBLK+1 ; setup to save all the randoms we can RNDMORE: jsr RNDNEXT ; get the next random sta RANDOM ; save it as the new seed sta ,X+ ; save it to the block cmpx #RNDBLK+254 ; have we reached the end? bne RNDMORE ; no, keep digging RNDEXIT: rts ; got our randoms get out ENDC ;********************************************************************* ;* END of code-rnd-v00.asm ;*********************************************************************