diff options
| -rw-r--r-- | life.asm | 173 |
1 files changed, 166 insertions, 7 deletions
@@ -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 |
