diff --git a/demos/life-src/life-src.lm b/demos/life-src/life-src.lm new file mode 100644 index 0000000..209a8eb --- /dev/null +++ b/demos/life-src/life-src.lm @@ -0,0 +1,316 @@ +; 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 +