#picaxe 28X2
#Slot 0
#no_table
#no_data
' #define debug
pause 4000
sertxd ("Conway LIFE v 5.bas",cr,lf)
#ifdef debug
setfreq m16
hsersetup B57600_16, %10
#else_if
setfreq em64
hsersetup B57600_64, %10
#endif
Symbol x = b0 ' w0
Symbol ccell = b1 ' w0
Symbol ncell = b2 ' w1
Symbol chng = b3 ' w1
Symbol ptr_2 = w2 ' b4 b5
Symbol LoopCount = b6 ' w3
Symbol y = b7 ' w3
Symbol x2 = b8 ' w4
Symbol y2 = b9 ' w4
Symbol ptr_s = w5
Symbol ptr_e = w6
Symbol AltBuff = w7
Symbol cpr = w8
Symbol GenCnt = w9
High C.2
' Empty scratchpad
for ptr = 0 to 255
@ptr = 0
next
#rem
' Build a Dot
' ---------------
' Live cells
put 35, $10
' Neighbour cells
put 18, $04
put 19, $04
put 20, $04
put 34, $04
put 36, $04
put 50, $04
put 51, $04
put 52, $04
put 35, $03
#endrem
#rem
' Build a Dot
' ---------------
' Live cells
put 167, $10
' Neighbour cells
put 150, $04
put 151, $04
put 152, $04
put 166, $04
put 168, $04
put 182, $04
put 183, $04
put 184, $04
#endrem
#rem
put 74, $03
put 76, $03
put 58, $03
put 60, $03
put 91, $03
#endrem
#rem
' Build a Blinker vert
' ---------------
' Live cells
put 35, $11
put 51, $12
put 67, $11
' Neighbour cells
put 18, $01
put 19, $01
put 20, $01
put 36, $02
put 52, $03
put 68, $02
put 84, $01
put 83, $01
put 82, $01
put 66, $02
put 50, $03
put 34, $02
' Build a Blinker hoz
' ---------------
' Live cells
put 182, $11
put 183, $12
put 184, $11
' Neighbour cells
put 197, $01
put 181, $01
put 165, $01
put 166, $02
put 167, $03
put 168, $02
put 169, $01
put 185, $01
put 201, $01
put 200, $02
put 199, $03
put 198, $02
#rem
put 57, $03
put 58, $03
put 219, $03
#endrem
' Build a Glider
' --------------
' Live cells
put 49,17
put 50,19
put 51,18
put 35,19
put 18,17
' Neighbour cells
put 1,1
put 2,1
put 3,1
put 17,1
put 19,2
put 20,1
put 32,1
put 33,3
put 34,5
put 36,2
put 48,1
put 52,2
put 64,1
put 65,2
put 66,3
put 67,2
put 68,1
' Copy buffer to alternate buffer
for LoopCount = 0 to 255
ptr = LoopCount
ptr_2 = LoopCount + 256
put ptr_2, @ptr
next
AltBuff = 256
' Show starting pattern
gosub DisplaySCR
do ' Main loop
' Calculate a generation
' ----------------------
ptr = 0
' Scan current buffer looking for live cells or cells with neighbors
For y = 0 to 15
For x = 0 to 15
' Get this generation
ccell = @ptr
' Test this generation
If ccell <> 0 then
' Lookup next generation state
' 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18
Lookup ccell, ($00,$01,$02,$13,$04,$05,$06,$07,$08,$00,$00,$00,$ 00,$00,$00,$00,$00,$01,$12,$13,$04,$05,$06,$07,$08 ), ncell
' Does it need to change ?
chng = ccell XOR ncell AND $10
If chng > 0 then
' Make pointer to buffer
ptr_2 = ptr + 256
' ( Next optimisation, pre-calculate offset to neighbours. )
' Make addresses of neighbours
If bit20 > 0 then ' Bit 4 of ncell, 1 = Birth, 0 = Death
get ptr_2, ncell ' Set cell On
ncell = ncell OR $10
put ptr_2, ncell
Gosub Birth ' Update neighbours
else
get ptr_2, ncell ' Set cell Off
ncell = ncell AND $0F
put ptr_2, ncell
Gosub Death ' Update neighbours
endif ' End of Birth/Death
endif ' End of changed ?
endif ' End of cell non-zero
inc ptr
Next x
Next y
' Show end result
gosub DisplaySCR
' Copy buffer,
for ptr = 0 to 255
ptr_2 = ptr + 256
get ptr_2, @ptr
next
toggle C.2
inc GenCnt
loop until GenCnt = 100
end
' Display scratchpads
' -------------------
DisplaySCR:
w20 = ptr
hserout 0,(128)
for ptr = 0 to 255
hserout 0,(@ptr)
next
ptr = w20
Return
' Increment neighbours
' --------------------
Birth:
#ifdef debug
sertxd ("Birth at x=",#x," y=",#y,cr,lf)
#endif
cpr = ptr ' Remember current cell ptr
' top left ' Increment neighbours (~ In alternate buffer ~ )
x2 = x - 1 AND 15
y2 = y - 1 AND 15
ptr = y2 * 16 + x2 + AltBuff
inc @ptr
#ifdef debug
sertxd ("tl x=",#x," y=",#y," ptr=",#ptr," val=",#@ptr,cr,lf)
#endif
' top centre
y2 = y - 1 AND 15
ptr = y2 * 16 + x + AltBuff
inc @ptr
#ifdef debug
sertxd ("tc x=",#x," y=",#y," ptr=",#ptr," val=",#@ptr,cr,lf)
#endif
' top right
x2 = x + 1 AND 15
y2 = y - 1 AND 15
ptr = y2 * 16 + x2 + AltBuff
inc @ptr
#ifdef debug
sertxd ("tr x=",#x," y=",#y," ptr=",#ptr," val=",#@ptr,cr,lf)
#endif
' mid left
x2 = x - 1 AND 15
ptr = y * 16 + x2 + AltBuff
inc @ptr
#ifdef debug
sertxd ("ml x=",#x," y=",#y," ptr=",#ptr," val=",#@ptr,cr,lf)
#endif
' mid right
x2 = x + 1 AND 15
ptr = y * 16 + x2 + AltBuff
inc @ptr
#ifdef debug
sertxd ("mr x=",#x," y=",#y," ptr=",#ptr," val=",#@ptr,cr,lf)
#endif
' bottom centre
y2 = y + 1 AND 15
ptr = y2 * 16 + x + AltBuff
inc @ptr
#ifdef debug
sertxd ("bc x=",#x," y=",#y," ptr=",#ptr," val=",#@ptr,cr,lf)
#endif
' bottom left
x2 = x - 1 AND 15
y2 = y + 1 AND 15
ptr = y2 * 16 + x2 + AltBuff
inc @ptr
#ifdef debug
sertxd ("bl x=",#x," y=",#y," ptr=",#ptr," val=",#@ptr,cr,lf)
#endif
' bottom right
x2 = x + 1 AND 15
y2 = y + 1 AND 15
ptr = y2 * 16 + x2 + AltBuff
inc @ptr
#ifdef debug
sertxd ("br x=",#x," y=",#y," ptr=",#ptr," val=",#@ptr,cr,lf)
#endif
ptr = cpr ' Restore cell ptr
Return
' Decrement neighbours
' --------------------
Death:
#ifdef debug
sertxd ("Death at x=",#x," y=",#y,cr,lf)
#endif
cpr = ptr ' Remember current cell ptr
' Decrement neighbours (~ In alternate buffer ~ )
' top left
x2 = x - 1 AND 15
y2 = y - 1 AND 15
ptr = y2 * 16 + x2 + AltBuff
dec @ptr
' mid left
x2 = x - 1 AND 15
ptr = y * 16 + x2 + AltBuff
dec @ptr
' bottom left
x2 = x - 1 AND 15
y2 = y + 1 AND 15
ptr = y2 * 16 + x2 + AltBuff
dec @ptr
' bottom centre
y2 = y + 1 AND 15
ptr = y2 * 16 + x + AltBuff
dec @ptr
' top centre
y2 = y - 1 AND 15
ptr = y2 * 16 + x + AltBuff
dec @ptr
' top right
x2 = x + 1 AND 15
y2 = y - 1 AND 15
ptr = y2 * 16 + x2 + AltBuff
dec @ptr
' mid right
x2 = x + 1 AND 15
ptr = y * 16 + x2 + AltBuff
dec @ptr
' bottom right
x2 = x + 1 AND 15
y2 = y + 1 AND 15
ptr = y2 * 16 + x2 + AltBuff
dec @ptr
ptr = cpr ' Restore cell ptr
Return