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
126
127
128
129
130
131
132
133
134
135
|
;;; 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
lda lineaddrs_l,x ; 5
sta pixptr ; 3
lda lineaddrs_h,x ; 5
sta pixptr+1 ; 3
move_pixel:
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 move_pixel
check_lru:
lda lineaddrs_l,x ; 5
sta pixptr ; 3
lda lineaddrs_h,x ; 5
sta pixptr+1 ; 3
; 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 move_pixel
check_lrd:
lda lineaddrs_l,x ; 5
sta pixptr ; 3
lda lineaddrs_h,x ; 5
sta pixptr+1 ; 3
; 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 move_pixel
stick:
rts
|