additional disassembly on life-src

This commit is contained in:
nino-porcino 2022-09-17 08:37:14 +02:00
parent 272601bc18
commit fd59a6c934
1 changed files with 107 additions and 70 deletions

View File

@ -2,11 +2,9 @@
; UNKNOWN AUTHOR ; UNKNOWN AUTHOR
; DISASSEMBLED BY ANTONINO PORCINO, 14TH SEP 2022 ; DISASSEMBLED BY ANTONINO PORCINO, 14TH SEP 2022
ECHO = $FFEF ; character echo routine in woz monitor ECHO = $FFEF ; character echo routine in Woz monitor
KEY_DATA = $D010 ; read key KEY_DATA = $D010 ; read key
KEY_CTRL = $D011 ; control port KEY_CTRL = $D011 ; control port
DSP_DATA = $D012 ; write ascii
DSP_CTRL = $D013 ; control port
; zero page variables ; zero page variables
@ -17,9 +15,18 @@ PTR4 = $F8 ; $F8-$F9
CELLCOUNT = $F9 ; also PTR4 high byte CELLCOUNT = $F9 ; also PTR4 high byte
RND = $FA ; $FA-$FB random seed RND = $FA ; $FA-$FB random seed
;
; board geometry is 40x24 = 960 bytes ; board geometry is 40x24 = 960 bytes
; there are two boards stored in memory:
; primary board: $2440-$27FF ; primary board: $2440-$27FF
; secondary board: $2840-$2BFF ; secondary board: $2840-$2BFF
;
; the boards contains the actual characters that are printed on
; the screen: live cell ("*"), dead cell (" ") and top/bottom border ("-")
;
BOARD = $2440
BOARDEND = $2800
ROW0 = $2440 ROW0 = $2440
ROW1 = $2468 ROW1 = $2468
@ -30,11 +37,11 @@ DEADCELL = $A0 ; " " (space character)
ALIVECELL = $AA ; "*" ALIVECELL = $AA ; "*"
FRAMECELL = $AD ; "-" FRAMECELL = $AD ; "-"
ORG $2000 ORG $2000
; ;
; quickly resets the primary board ($2400-$27FF) ; clears the primary board ($2400-$27FF)
; bug: the area between $2400-$243F is cleared as well
; ;
LDX #$00 LDX #$00
LDA #DEADCELL ; dead cell character LDA #DEADCELL ; dead cell character
@ -46,106 +53,128 @@ L2004 STA $2400,X ; bug: this should be $2440
BNE L2004 BNE L2004
; ;
; prints welcome message (56 characters) ; prints the welcome message (56 characters)
; X is zero from previous BNE ; (X is zero from previous BNE)
;
L2013 LDA MESSAGE,X L2013 LDA MESSAGE,X
JSR ECHO JSR ECHO
INX INX
CPX #$38 ; prints 56 chars CPX #56 ; prints 56 characters of the message
BNE L2013 BNE L2013
; read and print string from keyboard until ENTER is pressed ;
; string is simply discarded, the purpose is to increment the ; read and print from keyboard until ENTER is pressed
; random seed in $FA-RND+1 ; typed characters are simply discarded, the purpose
; is to increment the random seed in $FA-FB (RND variable)
;
L201E JSR RDKEY L201E JSR RDKEY
CMP #$8D ; enter key CMP #$8D ; enter key
BNE L201E BNE L201E
; ;
; fills the board with a random number of cells (from 32 to 95) ; fills the board with a random number of live cells (from 32 to 95)
; bug: also fills out of screen area between $2400 and $243F ; bug: also writes out of the screen area between $2400 and $243F
; ;
JSR GETRAND ; gets a random number JSR GETRAND ; gets a random number (0-255) in A
AND #$3F ; ranges it $00-$3F AND #$3F ; ranges it $00-$3F
ADC #$20 ; ranges it $20-$5F (TODO: why carry is not cleared?) ADC #$20 ; ranges it $20-$5F (why carry is not cleared?)
STA CELLCOUNT ; number of cells to write betwen $20-$5F (32-95) STA CELLCOUNT ; number of cells to generate betwen $20-$5F (32-95)
LDY #$00 LDY #$00 ; keeps Y to 0 for "STA(),Y" instruction
L2030 JSR GETRAND ; gets a random number L2030 JSR GETRAND ; gets a random number in A
AND #$03 ; ranges it 0-3 AND #$03 ; ranges it 0-3
CLC CLC
ADC #$24 ADC #BOARD/256 ; board high byte ($24)
STA PTR1+1 ; high byte ranges from $24-$27 STA PTR1+1 ; high byte now ranges from $24-$27
LDA RND LDA RND ; get random number directly from seed
STA PTR1 ; PTR1 points randomly $2400-$27FF STA PTR1 ; PTR1 now points randomly to $2400-$27FF
LDA #ALIVECELL ; alive cell character ("*") LDA #ALIVECELL ; alive cell character ("*")
STA (PTR1),Y ; set cell "ON" STA (PTR1),Y ; set cell "ON"
DEC CELLCOUNT ; decrement cell count DEC CELLCOUNT ; decrement cell counter
BNE L2030 ; loop until all cells are written BNE L2030 ; loop until all cells are written
;
;$2046 ;$2046
; main game loop ; main game loop
MAINLOOP LDA #$24 ;
STA PTR4+1 MAINLOOP LDA #BOARD/256 ;
LDA #$40 STA PTR4+1 ;
STA PTR4 ; PTR4 = $2440 LDA #BOARD%256 ;
STA PTR4 ; sets PTR4 to $2440
; ;
; marks top and bottom lines of the board to avoid out of bound checks ; marks top and bottom lines of the board to avoid out of bound checks
; ;
LDX #$27 ; $27=39, counts 40 characters backward LDX #39 ; counts 40 characters backward
LDA #FRAMECELL ; $AD = board limit character ("-") LDA #FRAMECELL ; board frame character ("-")
L2052 STA $27D8,X ; write bottom line of the board L2052 STA ROW23,X ; write bottom line of the board
STA $2440,X ; write top line of the board STA ROW0 ,X ; write top line of the board
DEX ; decrement 40 charc counter DEX ; decrement char counter
BPL L2052 ; loop if X >= 0 BPL L2052 ; loop if X >= 0
; loop that prints the whole board from $2440 to $2800 ;
; prints the whole board from $2440 to $2800
; Y is already zero from above
;
L205B LDA (PTR4),Y L205B LDA (PTR4),Y
JSR ECHO JSR ECHO
INC PTR4 INC PTR4
BNE L205B BNE L205B
INC PTR4+1 INC PTR4+1
LDA PTR4+1 LDA PTR4+1
CMP #$28 CMP #BOARDEND/256
BNE L205B BNE L205B
;
; reads the keyboard between each screen printout ; reads the keyboard between each screen printout
;
JSR RDKEY JSR RDKEY
; copy true board into "working" board (copies $2440-$2800 into $2840-...) ;
; copy primary board into secondary board (copies $2440-$27FF into $2840-$2BFF)
;
LDY #$00 LDY #$00
JSR SETPTRS ; PTR1=$2440, PTR2=$2840 JSR SETPTRS ; set board pointers: PTR1=$2440 (primary), PTR2=$2840 (secondary)
L2074 LDA (PTR1),Y L2074 LDA (PTR1),Y ; read from primary
STA (PTR2),Y STA (PTR2),Y ; write into secondary
INC PTR1 INC PTR1
INC PTR2 INC PTR2
BNE L2074 BNE L2074
INC PTR1+1 INC PTR1+1
INC PTR2+1 INC PTR2+1
LDA PTR1+1 LDA PTR1+1
CMP #$28 CMP #BOARDEND/256 ; check end of the board
BNE L2074 BNE L2074
JSR ZEROBOARD ; fills the primary board all with zeros ;
; once the primary board is copied, it's used to count the number of
; nearby cells around a live cell, so it's all set to 0
;
JSR ZEROBOARD
; ;
; scans the secondary board does some computation and writes on the primary board ; scans the secondary board: for every live cell increment by one
; the nearby cells in the primary board
;
; nearby cells are scanned using Y-indexing with the following Y values:
;
; -41 -40 -39
; -1 * +1
; 39 40 41
; ;
L208B LDY #$00 L208B LDY #$00
LDA (PTR2),Y LDA (PTR2),Y ; read cell in the secondary board
CMP #ALIVECELL ; is cell alive? CMP #ALIVECELL ; is cell alive?
BNE L209D ; if no go next cell BNE L209D ; if no go next cell
LDY #$27 ; yes it's alive LDY #39 ; yes it's alive, start Y indexing from 39
JSR L2114 ; ?? JSR SUM6CELLS ; sum cells with Y offsets: +/-39, +/-40, +/-41 (row above and below the live cell)
LDY #$01 LDY #1
JSR L211D ; ?? JSR SUMYCELLS ; sum cells with Y offsets: +/-1 (left/right of live cell)
; increment PTR1 and PTR2 to next cell ; increment PTR1 and PTR2 to next cell
L209D INC PTR1 L209D INC PTR1
@ -154,47 +183,56 @@ L209D INC PTR1
INC PTR1+1 INC PTR1+1
INC PTR2+1 INC PTR2+1
LDA PTR1+1 LDA PTR1+1
CMP #$28 ; check end of the board CMP #BOARDEND/256 ; check end of the board
BNE L208B BNE L208B
; ;
; ??? does something with top and bottom rows of the board ; sums the score from bottom row into top, and top into bottom
; this "wraps" the playfield making it like a toroid (sort of)
;
; ROW1 = ROW1 + ROW23 ; ROW1 = ROW1 + ROW23
; ROW22 = ROW22 + ROW0 ; ROW22 = ROW22 + ROW0
; why??
; ;
CLC CLC
LDX #$27 ; count 40 characters (1 row) LDX #39 ; count 40 characters (1 row)
L20B0 LDA ROW23,X L20B0 LDA ROW23,X
ADC ROW1,X ADC ROW1,X
STA ROW1,X STA ROW1,X
LDA ROW0,X LDA ROW0,X
ADC ROW22,X ADC ROW22,X ; (due to low score, carry it's always zero, no need to CLC)
STA ROW22,X STA ROW22,X
DEX DEX
BPL L20B0 BPL L20B0
JSR SETPTRS ;
; the actual GAME OF LIFE computation (Conway's rules)
; here secondary buffer contains the old board ("*" or " ")
; and primary buffer contains the number of nearby cells for each cell that is alive
;
JSR SETPTRS ; start from top of the boards
L20C8 LDY #$00 L20C8 LDY #$00
LDA (PTR1),Y LDA (PTR1),Y
CMP #$02 ; ? two cells around CMP #2 ; two cells nearby?
BNE L20D4 BNE L20D4 ; if not checks for three
LDA (PTR2),Y LDA (PTR2),Y ; yes two cells around: it survives to next round
BNE L20DE
L20D4 CMP #$03 ; ? three cells around
BNE L20DC
LDA #ALIVECELL ; set next cell alive
BNE L20DE BNE L20DE
L20D4 CMP #3 ; three cells nearby?
BNE L20DC ; if not then it's dead cell
LDA #ALIVECELL ; else it's alive (does not matter if it was alive or not)
BNE L20DE ; anything else is dead cell
L20DC LDA #DEADCELL ; set next cell dead L20DC LDA #DEADCELL ; set next cell dead
L20DE STA (PTR1),Y L20DE STA (PTR1),Y ; write the cell on the board
INC PTR1 INC PTR1
INC PTR2 INC PTR2
BNE L20C8 BNE L20C8
INC PTR1+1 INC PTR1+1
INC PTR2+1 INC PTR2+1
LDA PTR2+1 LDA PTR2+1
CMP #$2C CMP #$2C ; check end of the secondary board (ends at $2C00)
BNE L20C8 BNE L20C8
JMP MAINLOOP JMP MAINLOOP
; set pointers to: ; set pointers to:
@ -224,15 +262,14 @@ L2108 LDA KEY_CTRL
JSR ECHO JSR ECHO
RTS RTS
; ??? ; $2114
SUM6CELLS JSR SUMYCELLS
L2114 JSR L211D
INY INY
CPY #$2A CPY #$2A
BNE L2114 BNE SUM6CELLS
RTS RTS
;$211D
L211D ; increment cell at (PTR1),Y SUMYCELLS ; increment cell at (PTR1),Y
CLC CLC
LDA (PTR1),Y LDA (PTR1),Y
ADC #$01 ADC #$01
@ -293,9 +330,9 @@ L2167 STA (PTR1),Y
BNE L2167 BNE L2167
INC PTR1+1 INC PTR1+1
LDX PTR1+1 LDX PTR1+1
CPX #$28 ; check end of the board CPX #BOARDEND/256 ; check end of the board
BNE L2167 BNE L2167
JSR SETPTRS ; reset correct pointers on exit JSR SETPTRS ; reset correct pointers on exit
RTS RTS
L2179: L2179: