aboutsummaryrefslogtreecommitdiff
path: root/drunkwalk.s
diff options
context:
space:
mode:
Diffstat (limited to 'drunkwalk.s')
-rw-r--r--drunkwalk.s125
1 files changed, 125 insertions, 0 deletions
diff --git a/drunkwalk.s b/drunkwalk.s
new file mode 100644
index 0000000..ca80475
--- /dev/null
+++ b/drunkwalk.s
@@ -0,0 +1,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