Browse code

Game of life

neauoire authored on 06/05/2021 01:38:28
Showing 2 changed files
... ...
@@ -34,7 +34,7 @@ else
34 34
 fi
35 35
 
36 36
 echo "Assembling.."
37
-./bin/assembler projects/demos/drum-rack.usm bin/boot.rom
37
+./bin/assembler projects/demos/life.usm bin/boot.rom
38 38
 
39 39
 echo "Running.."
40 40
 if [ "${2}" = '--cli' ]; 
41 41
new file mode 100644
... ...
@@ -0,0 +1,213 @@
1
+( game of life )
2
+
3
+%+  { ADD } %-   { SUB }  %*  { MUL } %/   { DIV }  
4
+%<  { LTH } %>   { GTH }  %=  { EQU } %!   { NEQ } 
5
+%++ { ADD2 } %-- { SUB2 } %** { MUL2 } %// { DIV2 } 
6
+%<< { LTH2 } %>> { GTH2 } %== { EQU2 } %!! { NEQ2 }  
7
+
8
+%TOS { #00 SWP }
9
+%RTN { JMP2r }
10
+%MOD { DUP2 / * - }
11
+%SFL { #40 SFT SFT }
12
+
13
+%INCR { #01 + } %DECR { #01 - }
14
+
15
+%DEBUG { .Console/byte DEO #0a .Console/char DEO }
16
+%DEBUG2 { .Console/short DEO2 #0a .Console/char DEO }
17
+
18
+%GET-SIZE { WIDTH TOS #0008 // HEIGHT TOS ** }
19
+
20
+(
21
+	The maximum grid is 256x256, 
22
+	each byte is 8 horizontal cells,
23
+	the memory is 32x256[8192 bytes long]
24
+
25
+	The universe of the Game of Life is an infinite, two-dimensional orthogonal grid of square cells, 
26
+	each of which is in one of two possible states, live or dead,. Every cell interacts with its eight 
27
+	neighbours, which are the cells that are horizontally, vertically, or diagonally adjacent. 
28
+	At each step in time, the following transitions occur:
29
+
30
+    Any live cell with fewer than two live neighbours dies, as if by underpopulation.
31
+    Any live cell with two or three live neighbours lives on to the next generation.
32
+    Any live cell with more than three live neighbours dies, as if by overpopulation.
33
+    Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
34
+
35
+)
36
+
37
+%WIDTH { #40 } %HEIGHT { #40 }
38
+%BANK1 { #8000 }
39
+%BANK2 { #a000 }
40
+
41
+( devices )
42
+
43
+|00 @System     [ &vector $2 &wst      $1 &rst    $1 &pad   $4 &r      $2 &g     $2 &b      $2 ]
44
+|10 @Console    [ &pad    $8 &char     $1 &byte   $1 &short $2 &string $2 ]
45
+|20 @Screen     [ &vector $2 &width    $2 &height $2 &pad   $2 &x      $2 &y      $2 &addr  $2 &color $1 ]
46
+|80 @Controller [ &vector $2 &button   $1 &key    $1 ]
47
+|90 @Mouse      [ &vector $2 &x        $2 &y      $2 &state $1 &chord $1 ]
48
+
49
+( variables )
50
+
51
+|0000
52
+
53
+@timer $2
54
+@anchor [ &x $2 &y $2 ]
55
+
56
+( program )
57
+
58
+|0100 ( -> )
59
+
60
+	( theme ) 
61
+	#ef05 .System/r DEO2 
62
+	#cf05 .System/g DEO2 
63
+	#2f05 .System/b DEO2
64
+
65
+	( vectors )
66
+	;on-frame   .Screen/vector DEO2
67
+
68
+	( glider )
69
+	#07 #03 ;set-cell JSR2
70
+	#07 #04 ;set-cell JSR2
71
+	#05 #04 ;set-cell JSR2
72
+	#07 #05 ;set-cell JSR2
73
+	#06 #05 ;set-cell JSR2
74
+
75
+	.Screen/width DEI2 #0002 // WIDTH #02 / TOS SUB2 .anchor/x POK2
76
+	.Screen/height DEI2 #0002 // HEIGHT #02 / TOS SUB2 .anchor/y POK2
77
+
78
+BRK
79
+
80
+@on-frame ( -> )
81
+
82
+	.timer PEK #01 ADD [ DUP ] .timer POK
83
+
84
+	#08 MOD #00 ! #01 JNZ [ BRK ] 
85
+
86
+	( clear buffer )
87
+	BANK2 DUP2 GET-SIZE ++
88
+	&clear-loop
89
+		OVR2 #0000 SWP2 STA2
90
+		( incr ) SWP2 #0002 ADD2 SWP2
91
+		OVR2 OVR2 !! ,&clear-loop JNZ
92
+	POP2 POP2
93
+
94
+	;run-grid JSR2
95
+
96
+	( move buffer )
97
+	BANK2 DUP2 GET-SIZE ++
98
+	&copy-loop
99
+		OVR2 DUP2 LDA2 
100
+		SWP2 #2000 -- STA2
101
+		( incr ) SWP2 #0002 ADD2 SWP2
102
+		OVR2 OVR2 !! ,&copy-loop JNZ
103
+	POP2 POP2
104
+
105
+	( draw )
106
+	#00 HEIGHT
107
+	&ver
108
+		OVR TOS .anchor/y PEK2 ADD2 .Screen/y DEO2
109
+		OVR STH
110
+		#00 WIDTH
111
+		&hor
112
+			OVR TOS .anchor/x PEK2 ADD2 .Screen/x DEO2
113
+			OVR DUPr STHr ,get-cell JSR #01 + .Screen/color DEO
114
+			( incr ) SWP #01 + SWP
115
+			DUP2 ! ,&hor JNZ
116
+		POP2
117
+		POPr
118
+		( incr ) SWP #01 + SWP
119
+		DUP2 ! ,&ver JNZ
120
+	POP2
121
+
122
+BRK
123
+
124
+@get-index ( x y -- index* )
125
+	
126
+	HEIGHT MOD SWP WIDTH MOD SWP
127
+	WIDTH #08 / TOS ROT TOS ** ROT #08 / TOS ++ [ BANK1 ++ ]
128
+
129
+RTN
130
+
131
+@set-cell ( x y -- )
132
+	
133
+	DUP2 ,get-index JSR LDA STH
134
+	DUP2 POP #08 MOD #01 SWP SFL 
135
+	STHr SWP ORA STH
136
+	,get-index JSR STHr ROT ROT STA
137
+
138
+RTN
139
+
140
+@get-cell ( x y -- cell )
141
+	
142
+	DUP2 ,get-index JSR LDA 
143
+	SWP POP SWP
144
+	#08 MOD
145
+	SFT #01 AND
146
+
147
+RTN 
148
+
149
+@get-neighbours ( x y -- neighbours )
150
+	
151
+	( -1,-1 ) DUP2 DECR SWP DECR SWP ,get-cell JSR STH
152
+	(  0,-1 ) DUP2 DECR              ,get-cell JSR STH ADDr
153
+	( +1,-1 ) DUP2 DECR SWP INCR SWP ,get-cell JSR STH ADDr
154
+	( -1, 0 ) DUP2      SWP DECR SWP ,get-cell JSR STH ADDr
155
+	( +1, 0 ) DUP2      SWP INCR SWP ,get-cell JSR STH ADDr
156
+	( -1,+1 ) DUP2 INCR SWP DECR SWP ,get-cell JSR STH ADDr
157
+	(  0,+1 ) DUP2 INCR              ,get-cell JSR STH ADDr
158
+	( +1,+1 )      INCR SWP INCR SWP ,get-cell JSR STH ADDr
159
+	STHr
160
+
161
+RTN
162
+
163
+@run-grid ( -- )
164
+	
165
+	#00 HEIGHT
166
+	&ver
167
+		OVR STH
168
+		#00 WIDTH
169
+		&hor
170
+			OVR DUPr STHr STH2
171
+			( x y ) DUP2r STH2r
172
+			( neighbours ) DUP2r STH2r ,get-neighbours JSR
173
+			( state ) STH2r ;get-cell JSR2
174
+			,run-cell JSR
175
+			( incr ) SWP #01 + SWP
176
+			DUP2 ! ,&hor JNZ
177
+		POP2
178
+		POPr
179
+		( incr ) SWP #01 + SWP
180
+		DUP2 ! ,&ver JNZ
181
+	POP2
182
+
183
+RTN 
184
+
185
+@run-cell ( x y neighbours state -- )
186
+	
187
+	#00 = ,&dead JNZ
188
+	&alive
189
+		DUP #02 < ,&dies JNZ
190
+		DUP #03 > ,&dies JNZ
191
+		&lives POP ,save-cell JSR RTN
192
+		&dies POP POP2 RTN
193
+	&dead
194
+		DUP #03 = ,&birth JNZ POP POP2 RTN
195
+		&birth POP ,save-cell JSR RTN
196
+
197
+RTN
198
+
199
+@save-cell ( x y -- )
200
+	
201
+	,get-index-buffer JSR STH2
202
+	DUP2 POP #08 MOD #01 SWP SFL 
203
+	DUP2r LDAr STHr SWP ORA
204
+	STH2r STA
205
+
206
+RTN
207
+
208
+@get-index-buffer ( x y -- index* )
209
+	
210
+	HEIGHT MOD SWP WIDTH MOD SWP
211
+	WIDTH #08 / TOS ROT TOS ** ROT #08 / TOS ++ [ BANK2 ++ ]
212
+
213
+RTN