summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--life.asm173
1 files changed, 166 insertions, 7 deletions
diff --git a/life.asm b/life.asm
index 5544272..84f923e 100644
--- a/life.asm
+++ b/life.asm
@@ -9,11 +9,13 @@ GETIN := $ffe4
CHROUT := $ffd2
CLRCHN := $e544
+DEAD := $20
+ALIVE := $a0
+
; one byte for each cell, 1000 bytes because 40x25 screen; is identical to
; screen memory (i.e. $a0 is alive and $20 is dead)
-prev_grid := $0801
-; initialisation: clear screen and set num to point to screen mem start
+; initialisation: clear screen and set num $00
init:
; clear screen
lda #$93
@@ -44,6 +46,8 @@ loop:
beq if_reset
cmp #$20 ; fill cell if space pressed
beq if_space
+ cmp #$0d ; stop handling input and start life if return pressed
+ beq if_return
cmp #$30 ; end program if 0 pressed
bne loop
jmp end
@@ -81,18 +85,80 @@ if_space:
ldy #$00
lda (num2L),y
- cmp #$a0
+ cmp #ALIVE
beq if_cell_filled
jmp if_cell_empty
if_cell_filled:
- lda #$20
+ lda #DEAD
jsr print_byte
jmp loop
if_cell_empty:
- lda #$a0
+ lda #ALIVE
jsr print_byte
jmp loop
+; num is screen_mem; num2 is generation buffer, X is number of neighbours
+if_return:
+ ;jsr sleep
+
+ jsr copy_to_prev
+ lda #$00
+ sta numL
+ lda #$04
+ sta numH
+ lda #$00
+ sta num2L
+ lda #$c0
+ sta num2H
+
+
+; as per wikipedia, i'll just count the number of alive neighbours and the
+; cell itself, if the sum is 3 then it will be alive, if 4 then it'll retain
+; its state, otherwise it dies. X is number of neighbours
+life_loop:
+ ldx #$00
+
+ lda #41 ; cell to top left of current is row above minus 1
+ jsr s16b2
+ jsr cmp_row
+
+ lda #40 ; go back to cell left of current
+ jsr a16b2
+ jsr cmp_row
+
+ lda #40 ; go to cell below cell left of current
+ jsr a16b2
+ jsr cmp_row
+
+ ldy #$00
+
+ cpx #$03
+ beq if_to_live
+ cpx #$04
+ bne if_to_die
+ jmp if_retains
+
+if_to_live:
+ lda #ALIVE
+ sta (numL),y
+ jmp if_retains
+if_to_die:
+ lda #DEAD
+ sta (numL),y
+if_retains:
+
+ lda #38 ; go to right of current; restores num2 to original and increments
+ jsr s16b2
+ jsr inc_num
+
+ lda numH
+ cmp #$07
+ bne life_loop
+ lda numL
+ cmp #$e9
+ bne life_loop
+ jmp if_return
+
; print byte in A at location in screen_mem+num; destroys Y; num2 is expected
; to be $0400 (screen_mem zero location) and is set to that at the end
print_byte:
@@ -132,36 +198,50 @@ a16b2:
sta num2H
rts
-; subtracts A from num (destroys X)
+; subtracts A from num
s16b:
pha
+ txa
+ pha
+
lda numL
tsx
inx
+ inx
sec
sbc $0100,x
sta numL
lda numH
sbc #$00
sta numH
+
+ pla
+ tax
pla
rts
; might change functions to take from stack but this is easier for now as I
; only have 2 16 bit numbers to deal with anyways
-; subtracts A from num2 (destroys X)
+; subtracts A from num2
s16b2:
pha
+ txa
+ pha
+
lda num2L
tsx
inx
+ inx
sec
sbc $0100,x
sta num2L
lda num2H
sbc #$00
sta num2H
+
+ pla
+ tax
pla
rts
@@ -173,6 +253,14 @@ inc_H:
inc numH
rts
+inc_num2:
+ inc num2L
+ beq inc_H2
+ rts
+inc_H2:
+ inc num2H
+ rts
+
dec_num:
pha
@@ -188,5 +276,76 @@ dec_H:
pla
rts
+; num stores address in screen_mem; num2 stores address in generation buffer
+; destroys A and Y
+copy_to_prev:
+ lda #$00
+ sta numL
+ lda #$04
+ sta numH
+ lda #$00
+ sta num2L
+ lda #$c0
+ sta num2H
+ ldy #$00
+
+copy_to_prev_loop:
+ lda (numL),y
+ sta (num2L),y
+ ; might inline them instead of having subroutines for more speed, will see
+ ; if it makes difference if i have time
+ jsr inc_num
+ jsr inc_num2
+
+ lda numH
+ cmp #$07
+ bne copy_to_prev_loop
+ lda numL
+ cmp #$e9 ; e9 instead of e8 because last position is 07e8 but number is
+ ; increased before copying so it will be e8 before the number at e8 is copied
+ bne copy_to_prev_loop
+
+ rts
+
+; compare three numbers in a row in num2 with ALIVE and DEAD, increase X
+; accordingly
+cmp_row:
+ ldy #$00
+cmp_row_loop:
+ ; y will be between 0-2 to take into account row
+ lda (num2L),y
+ cmp #ALIVE
+ beq if_alive
+ jmp else_alive
+if_alive:
+ inx
+else_alive:
+ iny
+ cpy #$03
+ bne cmp_row_loop
+ rts
+
+sleep:
+ pha
+ lda #$00
+ ldx #$00
+ ldy #$00
+sleep_y_loop:
+ iny
+ jmp sleep_loop
+sleep_x_loop:
+ inx
+sleep_loop:
+ adc #$01
+ cmp #$ff
+ bne sleep_loop
+ cpx #$ff
+ bne sleep_x_loop
+ ;cpy #$ff
+ ;bne sleep_y_loop
+
+ pla
+ rts
+
end:
brk