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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
;;; Subroutine: drunkwalk
;;; Walk the point around randomly until it either is
;;; adjacent to a set pixel or goes out of bounds.
;;; Return with Z=0 if out of bounds, Z=1 if it hit a pixel.
;;; This is the innermost loop, so it should be as optimized as
;;; possible.
; Y and X are backwards: Y holds the X coordinate, and X holds the Y coordinate.
; Has to be, because there's no (zpind),x addressing mode.
oob:
rts
drunkwalk:
ldy part_x ; 3
ldx part_y ; 3
; do we need this now?
lda lineaddrs_l,x ; 5
sta pixptr ; 3
lda lineaddrs_h,x ; 5
sta pixptr+1 ; 3
bit RANDOM ; 4 ; use top 2 bits (probably more random, definitely faster)
bmi lr ; 2/3
bvc down ; 2/3
up:
dex ; 2 ; N=1 V=1 up
selfmod_ymin = * + 1
cpx #0 ; 2
beq oob ; 2
stx part_y
jmp check_lru
down:
inx ; 2 ; N=1 V=0 down
selfmod_ymax = * + 1
cpx #0 ; 2
beq oob ; 2
stx part_y
jmp check_lrd
lr:
bvc right ; 2/3
left:
dey ; 3 ; N=0 V=1 left
selfmod_xmin = * + 1
cpy #0 ; 2
beq oob ; 2
sty part_x
; check left neighbor (we just vacated the right one)
dey
lda (pixptr),y
bne stick
iny
jmp check_ud ; 3 ; still have to check Y (up/down) neighbors.
right:
iny ; 3 ; N=0 V=0 right
selfmod_xmax = * + 1
cpy #0 ; 2
beq oob ; 2
sty part_x
; check right neighbor (we just vacated the left one)
iny
lda (pixptr),y
bne stick
dey
; fall through to check_ud
check_ud:
; check up neighbor
lda lineaddrs_l-1,x
sta pixptr2
lda lineaddrs_h-1,x
sta pixptr2+1
lda (pixptr2),y
bne stick
; check down neighbor
lda lineaddrs_l+1,x
sta pixptr2
lda lineaddrs_h+1,x
sta pixptr2+1
lda (pixptr2),y
bne stick
jmp drunkwalk
check_lru:
; check left neighbor
dey
lda (pixptr),y
bne stick
iny
; check right neighbor
iny
lda (pixptr),y
bne stick
dey
; check up neighbor
lda lineaddrs_l-1,x
sta pixptr2
lda lineaddrs_h-1,x
sta pixptr2+1
lda (pixptr2),y
bne stick
jmp drunkwalk
check_lrd:
; check left neighbor
dey
lda (pixptr),y
bne stick
iny
; check right neighbor
iny
lda (pixptr),y
bne stick
dey
; check down neighbor
lda lineaddrs_l+1,x
sta pixptr2
lda lineaddrs_h+1,x
sta pixptr2+1
lda (pixptr2),y
bne stick
jmp drunkwalk
stick:
rts
|