~rabbits/uxn

uxn/projects/examples/demos/life.tal -rw-r--r-- 5.4 KiB
e00e74b9Andrew Alderwick (uxnasm) Raise an error if the output rom would be empty. 10 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
( Game Of Life:
	Any live cell with fewer than two live neighbours dies, as if by underpopulation.
	Any live cell with two or three live neighbours lives on to the next generation.
	Any live cell with more than three live neighbours dies, as if by overpopulation.
	Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction. )

|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2
|10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|30 @Audio0 &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1
|80 @Controller &vector $2 &button $1 &key $1
|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &wheel $1

|0000

@world &frame $1 &count $2
@anchor &x $2 &y $2 &x2 $2 &y2 $2
@pointer &x $2 &y $2

|0100 ( -> )

	( theme )
	#02cf .System/r DEO2
	#02ff .System/g DEO2
	#024f .System/b DEO2
	( resize )
	#00c0 .Screen/width DEO2
	#00c0 .Screen/height DEO2
	( vectors )
	;on-frame .Screen/vector DEO2
	;on-mouse .Mouse/vector DEO2
	;on-control .Controller/vector DEO2
	( glider )
	#07 #03 ;set-cell JSR2
	#07 #04 ;set-cell JSR2
	#05 #04 ;set-cell JSR2
	#07 #05 ;set-cell JSR2
	#06 #05 ;set-cell JSR2
	( center )
	.Screen/width DEI2 #01 SFT2 #0040 SUB2
		DUP2 .anchor/x STZ2
		#007e ADD2 .anchor/x2 STZ2
	.Screen/height DEI2 #01 SFT2 #0040 SUB2
		DUP2 .anchor/y STZ2
		#007e ADD2 .anchor/y2 STZ2

BRK

@on-frame ( -> )
	
	.Mouse/state DEI #00 EQU #01 JCN [ BRK ]
	#0000 .world/count STZ2
	.world/frame LDZ INC
		DUP .world/frame STZ
		#03 AND #00 EQU #01 JCN [ BRK ]
	;run JSR2
	&paused

BRK

@on-mouse ( -> )
	
	( clear last cursor )
	;cursor .Screen/addr DEO2
	.pointer/x LDZ2 .Screen/x DEO2
	.pointer/y LDZ2 .Screen/y DEO2
	#40 .Screen/sprite DEO
	( record pointer positions )
	.Mouse/x DEI2 DUP2 .pointer/x STZ2 .Screen/x DEO2
	.Mouse/y DEI2 DUP2 .pointer/y STZ2 .Screen/y DEO2
	( colorize on state )
	#42 [ .Mouse/state DEI #00 NEQ ] ADD .Screen/sprite DEO
	( on touch in rect )
	.Mouse/state DEI #00 NEQ #01 JCN [ BRK ]
	.Mouse/x DEI2 .Mouse/y DEI2 .anchor ;within-rect JSR2 JMP [ BRK ]
	( paint )
	.Mouse/x DEI2 .anchor/x LDZ2 SUB2 #01 SFT NIP
	.Mouse/y DEI2 .anchor/y LDZ2 SUB2 #01 SFT NIP
		;set-cell JSR2
	( draw )
	;draw-grid JSR2

BRK

@on-control ( -> )

	( toggle play )
	.Controller/key DEI #20 NEQ ,&no-toggle JCN
		;on-frame
		.Screen/vector DEI2 ;on-frame/paused EQU2 ,&swap JCN
			POP2 ;on-frame/paused
			&swap
		.Screen/vector DEO2
		&no-toggle
	( clear on home )
	.Controller/button DEI #08 NEQ ,&no-reset JCN
		;bank1 #0400 ;mclr JSR2
		&no-reset

BRK

@run ( -- )

	( clear buffer )
	;bank2 #1000 ;mclr JSR2
	( run grid )
	#4000
	&ver
		STHk
		#4000
		&hor
			DUP STHkr ,run-cell JSR
			INC GTHk ,&hor JCN
		POP2
		POPr
		INC GTHk ,&ver JCN
	POP2
	( move buffer )
	;bank2 ;bank1 #1000 ;mcpy JSR2
	( draw )
	;draw-grid JSR2

JMP2r

@run-cell ( x y -- )

	( x y ) DUP2
	( neighbours ) DUP2 ;get-neighbours JSR2
	( state ) ROT ROT ;get-cell JSR2
	#00 EQU ,&dead JCN
		DUP #02 LTH ,&dies JCN
		DUP #03 GTH ,&dies JCN
		POP ,&save JSR JMP2r
		&dies POP POP2 JMP2r
	&dead
		DUP #03 EQU ,&birth JCN POP POP2 JMP2r
		&birth POP ,&save JSR JMP2r

JMP2r
	&save ( x y -- ) 
		STH2 #01 STH2r ,get-index JSR [ #1000 ADD2 ] STA
		.world/count LDZ2 INC2 .world/count STZ2
	JMP2r

@get-index ( x y -- index* )
	
	( y ) #3f AND #00 SWP #60 SFT2 
	( x ) ROT #3f AND #00 SWP ADD2
		;bank1 ADD2

JMP2r

@set-cell ( x y -- )
	
	STH2 #01 STH2r ,get-index JSR STA

JMP2r

@get-cell ( x y -- cell )
	
	,get-index JSR LDA

JMP2r

@get-neighbours ( x y -- neighbours )
	
	,&origin STR2
	LITr 00
	#0800
	&loop
		#00 OVR #10 SFT2 ;&mask ADD2 LDA2 [ LIT2 &origin $2 ]
		ROT ADD STH ADD STHr ;get-cell JSR2 STH ADDr
		INC GTHk ,&loop JCN
	POP2
	STHr

JMP2r
	&mask ffff 00ff 01ff ff00 0100 ff01 0001 0101

@draw-grid ( -- )
	
	( draw cell count )
	.anchor/x LDZ2 .Screen/x DEO2
	.anchor/y2 LDZ2 #0008 ADD2 .Screen/y DEO2
	#01 .Screen/auto DEO
	.world/count LDZ2 ;draw-short JSR2
	#00 .Screen/auto DEO
	#4000
	&ver
		#00 OVR #10 SFT2 .anchor/y LDZ2 ADD2 .Screen/y DEO2
		STHk
		#4000
		&hor
			#00 OVR #10 SFT2 .anchor/x LDZ2 ADD2 .Screen/x DEO2
			DUP STHkr ;get-cell JSR2 INC .Screen/pixel DEO
			INC GTHk ,&hor JCN
		POP2
		POPr
		INC GTHk ,&ver JCN
	POP2

JMP2r

@draw-short ( short* -- )

	SWP ,draw-byte JSR

@draw-byte ( byte color -- )

	DUP #04 SFT ,draw-hex JSR #0f AND

@draw-hex ( char color -- )

	#00 SWP #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2
	#03 .Screen/sprite DEO

JMP2r

@within-rect ( x* y* rect -- flag )
	
	STH
	( y < rect.y1 ) DUP2 STHkr #02 ADD LDZ2 LTH2 ,&skip JCN
	( y > rect.y2 ) DUP2 STHkr #06 ADD LDZ2 GTH2 ,&skip JCN
	SWP2
	( x < rect.x1 ) DUP2 STHkr LDZ2 LTH2 ,&skip JCN
	( x > rect.x2 ) DUP2 STHkr #04 ADD LDZ2 GTH2 ,&skip JCN
	POP2 POP2 POPr
	#01
JMP2r
	&skip
	POP2 POP2 POPr
	#00

JMP2r

@mclr ( addr* len* -- )

	OVR2 ADD2 SWP2
	&loop
		STH2k #00 STH2r STA
		INC2 GTH2k ,&loop JCN
	POP2 POP2

JMP2r

@mcpy ( src* dst* len* -- )

	SWP2 STH2
	OVR2 ADD2 SWP2
	&loop
		LDAk STH2kr STA INC2r
		INC2 GTH2k ,&loop JCN
	POP2 POP2
	POP2r

JMP2r

@cursor
	80c0 e0f0 f8e0 1000

@font-hex
	7c82 8282 8282 7c00
	3010 1010 1010 3800
	7c82 027c 8080 fe00
	7c82 021c 0282 7c00
	2242 82fe 0202 0200
	fe80 807c 0282 7c00
	7c82 80fc 8282 7c00
	fe82 0408 0810 1000
	7c82 827c 8282 7c00
	7c82 827e 0202 0200
	7c82 82fe 8282 8200
	fc82 82fc 8282 fc00
	7c82 8080 8082 7c00
	fc82 8282 8282 fc00
	fe80 80f0 8080 fe00
	fe80 80f0 8080 8000

@bank1 $1000 @bank2