diff options
Diffstat (limited to 'drunkwalk.s')
| -rw-r--r-- | drunkwalk.s | 125 |
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 |
