        *= $0ffd

!to "ant.prg";

         ; langton's ant
         ; written by robert oestling
         ; 2005-01-23
         ; my first 6502 program. :-)
         jmp start
jmptbl   !word up,left,down,right
antx     !word 160 ; x coordinate
anty     !byte 100 ; y coordinate
mask     !byte $80 ; pos within byte
jmpadr   !word $1000
adr      = $b0     ; ptr to vidmem byte
dir      = $b2

start    lda #$a4
         sta adr
         lda #$2f
         sta adr+1 ; x=160,y=100,mask=1
         lda #$10
         sta dir+1
         lda #$00
         sta dir   ; start moving up
         sta $d020 ; border = black
         sta $d021 ; background = black
         ldy #$20  ; $2000 to counter
         sty clr1+2
clr0     ldx #$00
clr1     sta $2000,x
         dex
         bne clr1  ; clear $100 bytes
         inc clr1+2
         dey
         bne clr0
         lda #$16
clr3     sta $0400,y
         sta $0500,y
         sta $0600,y
         sta $0700,y ; clear char area
         dey
         bne clr3
         lda #$3b
         sta $d011 ; bitmap mode
         lda #$08
         sta $d016 ; single-color mode
         lda #$18
         sta $d018 ; bitmap at $2000

move     ldy #$00
         lda (dir),y
         sta jmpadr
         iny
         lda (dir),y ; adr at (dir) to
         sta jmpadr+1 ; jmpadr
         jmp (jmpadr)
up       lda anty
         bne up0 ; y=0?
         lda #$c7
         sta anty ; yes, 199->y
         lda adr
         clc
         adc #$07
         sta adr
         lda adr+1
         adc #$1e
         sta adr+1 ; jump to bottom
         jmp moved
up0      dec anty
         and #$07 ; bottom of 8x8 bits?
         bne up1
         lda adr
         sec
         sbc #$39
         sta adr
         lda adr+1
         sbc #$01
         sta adr+1 ; one row down
         jmp moved
up1      lda adr
         sec
         sbc #$01
         sta adr
         bcs up2
         dec adr+1 ; one row down
up2      jmp moved
down     lda anty
         cmp #$c7 ; y=199?
         bne down0
         lda #$00
         sta anty ; yes, 0->y
         lda adr
         sec
         sbc #$07
         sta adr
         lda adr+1
         sbc #$1e
         sta adr+1 ; jump to top
         jmp moved
down0    inc anty
         and #$07
         cmp #$07 ; top of 8x8 bits?
         bne down1
         lda adr
         clc
         adc #$39
         sta adr
         lda adr+1
         adc #$01
         sta adr+1 ; one row down
         jmp moved
down1    lda adr
         clc
         adc #$01
         sta adr
         bcc down2
         inc adr+1 ; one row down
down2    jmp moved
left     lda antx
         bne left0
         lda antx+1
         bne left0
         lda #$3f
         sta antx
         lda #$01
         sta antx+1 ; 319->antx
         lda #$01
         sta mask ; rightmost pixel
         lda adr
         clc
         adc #$38
         sta adr
         lda adr+1
         adc #$01
         sta adr+1 ; wrap around
         jmp moved
left0    lda antx
         sec
         sbc #$01
         sta antx
         bcs left1
         dec antx+1 ; sub 1 from antx
left1    asl mask
         bcc moved
         lda #$01
         sta mask ; rightmost pixel
         lda adr
         sec
         sbc #$08
         sta adr
         bcs moved
         dec adr+1 ; one pixel left
         bcc moved
right    lda antx
         cmp #$3f
         bne right0
         lda antx+1
         beq right0
         lda #$80
         sta mask ; leftmost pixel
         lda #$00
         sta antx
         sta antx+1 ; 0->antx
         lda adr
         sec
         sbc #$38
         sta adr
         lda adr+1
         sbc #$01
         sta adr+1 ; wrap around
         jmp moved
right0   lda antx
         clc
         adc #$01
         sta antx
         bcc right1
         inc antx+1 ; add 1 to antx
right1   lsr mask
         bcc moved
         lda #$80
         sta mask ; leftmost pixel
         lda adr
         clc
         adc #$08
         sta adr
         bcc moved
         inc adr+1 ; one pixel right
moved    lda mask
         ldy #$00
         eor (adr),y
         sta (adr),y
         and mask
         clc
         bne turn0
         lda dir
         adc #$02 ; turn right
         and #$07
         sta dir
         jmp move
turn0    lda dir
         sbc #$01 ; turn left
         and #$07
         sta dir
         jmp move



