org 0 bits_old: dw 0 neighbor_count: db 0 tmp: db 0 org $200 get_cell: ; assumes: ZP "bits_old" points at the right location ; input: Linear cell # in A. (OR possibly the X-coordinate if 32x16, Y coordinate accounted in bits_old) ; output: Carry set if cell is live ; destroys x, y ; caller can then restore its neighbor count (LDA doesn't set C) and ADC #$0 to increment it or not tax ; we need a copy later and #$7 tay ; now y has the shift distance txa ; told ya lsr lsr lsr ; shift out the low bits tax ; now x has the offset of the byte of interest lda bits_old,x ; now a register has the relevant byte get_cell_loop: ; shift 1 to 8 times (not 0 to 7) so relevant bit is in carry asl dey bne get_cell_loop rts census_cell: ; input: Linear cell # in A ; side effect: updates neighbor_count ; output: the new value of neighbor_count is in A -- this property is not used ; stack used: 2 ; destroys all registers jsr get_cell lda neighbor_count adc #$0 sta neighbor_count rts ; These move routines are for 16x16 boards, not 32x32 move_up: ; input: Linear cell# in A ; output: new linear cell# in A clc sbc #16 rts move_down: ; input: Linear cell# in A ; output: new linear cell# in A clc sbc #16 rts move_right: ; input: Linear cell# in A ; output: new linear cell# in A ; destroys: x, y, tmp tay and #$F0 sta tmp tya clc adc #01 ; no inc a!! and #$0F ora tmp rts move_left: ; input: Linear cell# in A ; output: new linear cell# in A ; destroys: tmp ; stack used: 1 pha and #$F0 sta tmp pla clc ; no dec a!! sbc #01 and #$0F ora tmp rts compute_cell: ldx #0 stx neighbor_count jsr move_left jsr census_cell jsr move_up jsr census_cell jsr move_right jsr census_cell jsr move_right jsr census_cell jsr move_down jsr census_cell jsr move_down jsr census_cell jsr move_left jsr census_cell jsr move_left jsr census_cell jsr move_up jsr census_cell jsr move_up jsr census_cell jsr move_right jsr get_cell lda #0 adc #0 ; a now holds 0 if dead, 1 if live. **CARRY IS CLEAR** ora neighbor_count ; a now holds neighbor_count if dead, or neighbor_count | 1 if live, so 2->3 if live cmp #3 ; now if should live or be born, A has 0 lda #0 sbc #0 ; CF has "should live or be born" ; fall through to put cell put_cell: ; to be done ; input: CF flag for new cell live/dead status ; notes: if you assume that cells are always put in order .. ; preload a byte with #$01 (or maybe #$80? depending on shift direction) and shift each new bit in ; as soon as you *shift out* a 1 into carry, you need to go on to the next byte brk