Back to Page
Revision 1 (current)
Edited by Randomno on 7/3/2023 1:51 PM
! RNG
This code describes the RNG for FDS Backgammon.
At the title screen, the RNG begins at one of 32 possible sequences (0-31), and runs through the sequence one number per frame. When the title screen is cleared, the RNG stops and all dice rolls are determined.
Power-on uses sequence 31. For other sequences, do a reset when memory address $33 is the sequence number mod 32.
Because all dice rolls for a game are determined before it begins, nothing useful will likely occur, given that GBC Backgammon dice rolls can be manipulated just before rolling the dice. At least 17 rolls (some of them high doubles) must be done by both sides to complete the game. If a home board shutout is performed with an opposing piece on the bar, this prevents the opponent from making a roll, but the added flexibility is very small.
%%SRC_EMBED snescom
;initial seed function, one of 32 values
$6245:
LDX $33 ;incrementing value, not cleared on reset, used as seed
...
LDA #0
$6254:
STA $10,Y ;probably some clearing routine
DEY
BNE $6254
DEC $11
BPL $6254
TXA
BNE $6262
LDX #$5F ;power-on value used as seed
$6262:
STX $500 ;put seed here
;initial 55 values
;recursion is length 55 and mod 180
;first 55 values depend on one of 32 seeds
$9CAB:
LDA $500 ;take seed
AND #$1F ;mod 32
STA $10 ;put in mem10
STA $637
LDA #$1
STA $11 ;mem11=1
LDY #$14 ;offset starts at 20 and will increment by 21 (mod 55)
LDX #$36 ;X=54, 55 iterations
CreateValue:
LDA $11
STA $601,Y ;store mem11 at index
LDA $10
SEC
SBC $11 ;A=mem10 - mem11
BPL $9CCC
CLC
ADC #$B4 ;mod 180
$9CCC:
STA $11 ;new value for mem11 and next index
LDA $601,Y ;back to this index
STA $10 ;put in mem10
TYA
CLC
ADC #$15 ;add 21 to offset
CMP #$37
BCC $9CDD
SBC #$37 ;mod 55
$9CDD:
TAY ;new index
DEX ;next
BNE CreateValue ;if 0 done
;now execute RndFunc 3 times
JSR RndFunc ;$9CE7
JSR RndFunc
;(falling into RndFunc)
;Recursion function
;Technically it throws 55 new numbers at once
;since it uses $600 as a pointer into a 55-number array
;It works like this: x_n = x_(n-55) - x_(n-24) (mod 180)
RndFunc:
$9CE7:
LDY #$0 ;initial
Next:
$9CE9:
TYA ;A=Y (index)
STA $10 ;mem10 = A
CMP #$18
BCS $9CF4 ;this is basically A-24 (mod 55)
ADC #$1F
BCC $9CF6
$9CF4:
SBC #$18
$9CF6:
TAY ;used as index
LDA $601,Y
STA $11 ;take value at index-24 and store in mem11
LDY $10 ;Y=original index
LDA $601,Y ;A=index value
SEC
SBC $11 ;A-=mem11
BCS $9D08
ADC #$B4 ;mod 180
$9D08:
STA $601,Y ;new value
INY ;next index
CPY #$37 ;if index reaches 55, done
BNE Next
LDA #0 ;start at index 0
STA $600
TAY
LDA $601,Y ;(first value)
RTS
; this calls a random value; used in GetDiceRoll
GetRandomVal:
INC $600 ;increment index
LDA $600 ;index
CMP $37
BCC NotOverflow ;if overflow execute RndFunc
JSR RndFunc
LDA #$0 ;totally redundant
STA $600
$9CA6: NotOverflow:
TAY
LDA $601,Y ;value at index
RTS
; determine dice roll
GetDiceRoll:
$815C:
LDA $30C
BNE Return ;if not ready, do nothing
JSR GetRandomVal ;$9C94
LDY #$0
$8166:
CMP #$24
BCC $816F
SBC #$24 ;mod 36, Y=A/36 A%=36
INY
BCS $8166
$816F:
STA $10 ;mem10=A
TYA
STA $11 ;mem11=Y
ASL
ASL
ASL ;8*Y
SEC
SBC $11 ;7*Y
CLC
ADC $10 ;7*Y+A
CMP #$24
BCC $8183
SBC #$24 ;mod 36
TAY
LDA LookUpTable,Y ;refer to look-up table 0<=Y<=35 81CF-81F2
PHA
LSR
LSR
LSR
LSR
STA $46 ;idiv 16 upperhalfbyte, die 1
PLA
AND #$F ;mod 16 lowerhalfbyte, die 2
STA $47
...
Return:
RTS
;all values of the look-up table denote upper-lower paired representation of a dice roll
LookUpTable:
$81CF:
$14 $66 $36 $65 $63 $11
$23 $33 $16 $31 $21 $53
$51 $61 $62 $35 $44 $22
$12 $32 $55 $34 $56 $25
$13 $43 $41 $42 $46 $15
$24 $52 $45 $26 $64 $54
%%END_EMBED