aboutsummaryrefslogtreecommitdiff
path: root/rand.s
blob: af4b69369f275e8520a21dcf06651d993babadc5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

 .export _randb, _randi, _randl
; .export _rand1in5
; .export _randbit
 .importzp sreg, tmp3

 .include "atari.inc"

; RANDOM is the POKEY LFSR read address. This appears to be the low 8
; bits of a 17-bit LFSR (Atari calls it a poly counter). Unfortunately,
; a read from this address will never return 0, since LFSR's can't do
; that. If Atari had made the RANDOM register read the higher order bits
; of the LFSR, rather than the bottom 8, this wouldn't be a problem... but
; they didn't, so there's extra code in here to (try to) compensate.

; Might use this at some point:
;_randbit:
; lda RANDOM
; asl
; lda #0
; adc #0
; rts

; unsigned char __fastcall__ randbit(void);
;_randbit:
; ldx #0
;randbit:
; lda RANDOM
; lsr
; and #$01
; rts

; This doesn't give evenly distributed results, it's twice as
; likely to return 2 or 3 than 0, 1, or 4.
; unsigned char __fastcall__ rand1in5(void);
;_rand1in5:
; ldx #0
;rand1in5:
; lda RANDOM
; lsr
; lsr
; and #$03
; adc #0
; rts


; unsigned char __fastcall__ randb(void);
_randb: ; C-callable entry point
 ldx #0
randb:  ; asm-callable (doesn't trash X reg)
 lda RANDOM ; bit 7 of this read ends up as bit 0 of result
 sta tmp3
 nop        ; let the LFSR cook for a bit...
 nop
 lda RTCLOK+2 ; different amount of cooking depending on whether
 and #$01     ; we're on an even or odd numbered TV frame
 bne @1
 nop
 nop
 nop
@1:
 rol tmp3   ; tmp3 bit 7 now in carry
 lda RANDOM
 rol        ; carry now in bit 0 of A
 nop
 nop
 rts

; unsigned int __fastcall__ randi(void);
; NB cc65's rand() returns a positive signed int, meaning
; 0 to 0x7fff.
_randi:
 jsr randb
 and #$7f
 tax
 jsr randb
 rts

; unsigned long __fastcall__ randl(void);
; this returns the full range of an unsigned long, 0 to 2**32-1
_randl:
 jsr randb
 sta sreg
 jsr randb
 sta sreg+1
 jsr randb
 tax
 jsr randb
 rts