; LIFE FOR APPLE-1 ; UNKNOWN AUTHOR ; DISASSEMBLED BY ANTONINO PORCINO, 14TH SEP 2022 ECHO = $FFEF ; character echo routine in woz monitor KEY_DATA = $D010 ; read key KEY_CTRL = $D011 ; control port DSP_DATA = $D012 ; write ascii DSP_CTRL = $D013 ; control port ; zero page variables PTR1 = $F0 ; $F0-$F1 PTR2 = $F2 ; $F2-$F3 PTR3 = $F6 ; $F6-$F7 PTR4 = $F8 ; $F8-$F9 CELLCOUNT = $F9 ; also PTR4 high byte RND = $FA ; $FA-$FB random seed ; board geometry is 40x24 = 960 bytes ; primary board: $2440-$27FF ; secondary board: $2840-$2BFF ROW0 = $2440 ROW1 = $2468 ROW22 = $27B0 ROW23 = $27D8 DEADCELL = $A0 ; " " (space character) ALIVECELL = $AA ; "*" FRAMECELL = $AD ; "-" ORG $2000 ; ; quickly resets the primary board ($2400-$27FF) ; LDX #$00 LDA #DEADCELL ; dead cell character L2004 STA $2400,X ; bug: this should be $2440 STA $2500,X STA $2600,X STA $2700,X INX BNE L2004 ; ; prints welcome message (56 characters) ; X is zero from previous BNE L2013 LDA MESSAGE,X JSR ECHO INX CPX #$38 ; prints 56 chars BNE L2013 ; read and print string from keyboard until ENTER is pressed ; string is simply discarded, the purpose is to increment the ; random seed in $FA-RND+1 L201E JSR RDKEY CMP #$8D ; enter key BNE L201E ; ; fills the board with a random number of cells (from 32 to 95) ; bug: also fills out of screen area between $2400 and $243F ; JSR GETRAND ; gets a random number AND #$3F ; ranges it $00-$3F ADC #$20 ; ranges it $20-$5F (TODO: why carry is not cleared?) STA CELLCOUNT ; number of cells to write betwen $20-$5F (32-95) LDY #$00 L2030 JSR GETRAND ; gets a random number AND #$03 ; ranges it 0-3 CLC ADC #$24 STA PTR1+1 ; high byte ranges from $24-$27 LDA RND STA PTR1 ; PTR1 points randomly $2400-$27FF LDA #ALIVECELL ; alive cell character ("*") STA (PTR1),Y ; set cell "ON" DEC CELLCOUNT ; decrement cell count BNE L2030 ; loop until all cells are written ;$2046 ; main game loop MAINLOOP LDA #$24 STA PTR4+1 LDA #$40 STA PTR4 ; PTR4 = $2440 ; ; marks top and bottom lines of the board to avoid out of bound checks ; LDX #$27 ; $27=39, counts 40 characters backward LDA #FRAMECELL ; $AD = board limit character ("-") L2052 STA $27D8,X ; write bottom line of the board STA $2440,X ; write top line of the board DEX ; decrement 40 charc counter BPL L2052 ; loop if X >= 0 ; loop that prints the whole board from $2440 to $2800 L205B LDA (PTR4),Y JSR ECHO INC PTR4 BNE L205B INC PTR4+1 LDA PTR4+1 CMP #$28 BNE L205B ; reads the keyboard between each screen printout JSR RDKEY ; copy true board into "working" board (copies $2440-$2800 into $2840-...) LDY #$00 JSR SETPTRS ; PTR1=$2440, PTR2=$2840 L2074 LDA (PTR1),Y STA (PTR2),Y INC PTR1 INC PTR2 BNE L2074 INC PTR1+1 INC PTR2+1 LDA PTR1+1 CMP #$28 BNE L2074 JSR ZEROBOARD ; fills the primary board all with zeros ; ; scans the secondary board does some computation and writes on the primary board ; L208B LDY #$00 LDA (PTR2),Y CMP #ALIVECELL ; is cell alive? BNE L209D ; if no go next cell LDY #$27 ; yes it's alive JSR L2114 ; ?? LDY #$01 JSR L211D ; ?? ; increment PTR1 and PTR2 to next cell L209D INC PTR1 INC PTR2 BNE L208B INC PTR1+1 INC PTR2+1 LDA PTR1+1 CMP #$28 ; check end of the board BNE L208B ; ; ??? does something with top and bottom rows of the board ; ROW1 = ROW1 + ROW23 ; ROW22 = ROW22 + ROW0 ; why?? ; CLC LDX #$27 ; count 40 characters (1 row) L20B0 LDA ROW23,X ADC ROW1,X STA ROW1,X LDA ROW0,X ADC ROW22,X STA ROW22,X DEX BPL L20B0 JSR SETPTRS L20C8 LDY #$00 LDA (PTR1),Y CMP #$02 ; ? two cells around BNE L20D4 LDA (PTR2),Y BNE L20DE L20D4 CMP #$03 ; ? three cells around BNE L20DC LDA #ALIVECELL ; set next cell alive BNE L20DE L20DC LDA #DEADCELL ; set next cell dead L20DE STA (PTR1),Y INC PTR1 INC PTR2 BNE L20C8 INC PTR1+1 INC PTR2+1 LDA PTR2+1 CMP #$2C BNE L20C8 JMP MAINLOOP ; set pointers to: ; PTR1 = $2440 ; PTR2 = $2840 ; $20F3 SETPTRS LDA #$24 STA PTR1+1 LDA #$28 STA PTR2+1 LDA #$40 STA PTR1 STA PTR2 RTS ; $2102 ; reads a key and displays it on the terminal ; returns key in A ; increments a time counter $FA-$FB ; RDKEY INC RND BNE L2108 INC RND+1 L2108 LDA KEY_CTRL BPL RDKEY LDA KEY_DATA JSR ECHO RTS ; ??? L2114 JSR L211D INY CPY #$2A BNE L2114 RTS L211D ; increment cell at (PTR1),Y CLC LDA (PTR1),Y ADC #$01 STA (PTR1),Y STY CELLCOUNT ; save Y into CELLCOUNT ; PTR3 = PTR1 - Y SEC LDA PTR1 SBC CELLCOUNT STA PTR3 LDA PTR1+1 SBC #$00 STA PTR3+1 ; increment cell at (PTR3),Y e.g. (PTR1),-Y LDY #$00 LDA (PTR3),Y CLC ADC #$01 STA (PTR3),Y LDY CELLCOUNT ; restores Y RTS ; ;$213F ; (possibly) advances the random number generator ; and loads a random number into A ; uses PTR3 as temporary variable? GETRAND LDA RND+1 STA PTR3 LDA RND ASL A ROL PTR3 ASL A ROL PTR3 CLC ADC RND PHA LDA PTR3 ADC RND+1 STA RND+1 PLA ADC #$11 STA RND LDA RND+1 ADC #$36 STA RND+1 RTS ;$2161 ;fills the primary board ($2440-$27FF) all with $00 ZEROBOARD JSR SETPTRS LDA #$00 TAY L2167 STA (PTR1),Y INC PTR1 BNE L2167 INC PTR1+1 LDX PTR1+1 CPX #$28 ; check end of the board BNE L2167 JSR SETPTRS ; reset correct pointers on exit RTS L2179: DB A0 ; unused byte ; $2180 MESSAGE: DB $A0,$A0,$A0,$A0,$A0,$A0,$8D,$8D DB $8D,$8D,$C3,$CF,$CE,$D7,$C1,$D9 DB $A7,$D3,$A0,$C7,$C1,$CD,$C5,$A0 DB $CF,$C6,$A0,$CC,$C9,$C6,$C5,$8D DB $8D,$D0,$CC,$C5,$C1,$D3,$C5,$A0 DB $D4,$D9,$D0,$C5,$A0,$D9,$CF,$D5 DB $D2,$A0,$C6,$D5,$CC,$CC,$A0,$CE DB $C1,$CD,$C5,$AE,$8D,$8D,$00 // $21B9