-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathday21_lib.tal
324 lines (256 loc) · 7.4 KB
/
day21_lib.tal
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
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
~library/console.lib.tal
~library/string.tal
~library/math.tal
%STATEPAD { $5 } %STATESIZE { #0005 }
%STATE.pos1 { }
%STATE.pos2 { #0001 ADD2 }
%STATE.score1 { #0002 ADD2 }
%STATE.score2 { #0003 ADD2 }
%STATE.nextup { #0004 ADD2 }
%STATELISTPAD { $1000 } %STATELISTSIZE { #1000 }
%POSCOUNT { #0a }
%WINSCORE { #0015 }
%COUNTSIZE { #0008 } %COUNTPAD { $8 }
@state
( st* player1pos player2pos player1score player2score nextup -- )
&init
STH STH STH STH STH
STH2k STAr
INC2 STH2k STAr
INC2 STH2k STAr
INC2 STH2k STAr
INC2 STH2 STAr
RTN
( st* -- )
&print
&dump
LIT '[ EMIT
LDAk DBGBYTEDECn SP POP
INC2 LDAk DBGBYTEDECn SP POP
INC2 LDAk DBGBYTEDECn SP POP
INC2 LDAk DBGBYTEDECn SP POP
INC2 LDA DBGBYTEDECn POP
LIT '] EMIT
RTN
( stout* stin* -- )
©
SWP2
STATESIZE ;memcpy JSR2 ( stout* : dicesum )
RTN
( st1* st2* -- equal )
&equal
STH2 ( st1* : st2* )
LDAk LDArk STHr NEQ ,&equal/not JCN
INC2 INC2r
LDAk LDArk STHr NEQ ,&equal/not JCN
INC2 INC2r
LDAk LDArk STHr NEQ ,&equal/not JCN
INC2 INC2r
LDAk LDArk STHr NEQ ,&equal/not JCN
INC2 INC2r
LDA LDAr STHr NEQ ,&equal/not JCN
#01 RTN
&equal/not
POP2 POP2r
#00 RTN
( stout* stin* dicesum -- )
&advance
STH
( stout* stin* : dicesum )
OVR2 SWP2 ( stout* stout* stin* : dicesum )
;© JSR2 ( stout* : dicesum )
[ DUP2 STATE.nextup LDA ] [ #00 SWP ;&advance/offset STA2 ]
( stout* : dicesum )
DUP2 STATE.pos1 [ ;&advance/offset LDA2 ] ADD2 ( stout* pos* : dicesum )
LDAk STHr ADD ( stout* pos* pos+dicesum )
DEC #0a MOD INC ( stout* pos* (pos+dicesum)-1)%10+1 )
STHk ROT ROT STA ( stout* : newpos )
DUP2 STATE.score1 [ ;&advance/offset LDA2 ] ADD2 ( stout* score* : newpos )
LDAk STHr ADD ( stout* score* newscore )
( stout* score* newscore )
ROT ROT STA ( stout* )
( toggle nextup )
STATE.nextup ( nextup* )
LDAk #01 EOR ROT ROT STA
RTN
[ &advance/offset $2 ]
@universes
( pos1 pos2 -- )
&init
STH STH
;&init/st STHr STHr #00 #00 #00 ;state/init JSR2
;statebuf/init JSR2
;&init/count #0001 ;short-to-64 JSR2
;&init/st ;&init/count ;statebuf/add JSR2
#00 [ ;&nextup STA ]
( byte cnt dest* -- )
( #00 COUNTSIZE 2** ;&wins ;memset JSR2 )
RTN
[ &init/count COUNTPAD &init/st STATEPAD ]
( -- )
&dump
;statebuf/dump JMP2
( -- count )
&count
;statebuf/count JMP2
( -- )
&advance
#00 [ ;&advance/advanced STA ]
[ ;&nextup LDA ] ;&advance/from ;statebuf/nextup-foreach JSR2
[ ;&nextup LDA ] #01 EOR [ ;&nextup STA ]
[ ;&advance/advanced LDA ]
RTN
( st* count* -- again )
&advance/from
#01 [ ;&advance/advanced STA ]
;&advance/count SWP2 ;copy64 JSR2
DUP2 ;&advance/stfrom SWP2 ;state/copy JSR2
;statebuf/clear JSR2
#0003 #000a DO
STHk ;&advance/st2 ;&advance/stfrom STHr ;state/advance JSR2
( todo multiply count by dice sum repeats )
;&advance/count-multiplied ;&advance/count ;copy64 JSR2
DUP2 #0003 SUB2 ;&dice-repeats ADD2 LDA STH ( : repeats )
;&advance/count-multiplied STHr ;mul64-byte JSR2
;&advance/st2 STATE.score1 [ ;&nextup LDA ] #00 SWP ADD2 LDA #00 SWP
( score )
WINSCORE LTH2 ,&advance/no-win JCN
[ ;&nextup LDA ] #00 SWP 8** ( 8*nextup )
;&wins ADD2 ( wins* )
;&advance/count-multiplied ;add64 JSR2
,&advance/next-roll JMP
&advance/no-win
;&advance/st2 ;&advance/count-multiplied ;statebuf/add JSR2
&advance/next-roll
LOOP
RTN
[ &advance/stfrom STATEPAD &advance/st2 STATEPAD &advance/count COUNTPAD &advance/count-multiplied COUNTPAD
&advance/advanced $2 ]
[ &nextup $1 &wins &p1wins COUNTPAD &p2wins COUNTPAD
&dice-repeats 01 03 06 07 06 03 01 ]
@statebuf
&init
#00 POSCOUNT POSCOUNT MUL 2* ;paging-init JSR2
RTN
( st* -- )
&clear
( st* )
;&addr JSR2
( pagenum offset )
;&clear/zero ROT2 ROT2 ;&store JSR2
RTN
[ &clear/zero 00 00 00 00 00 00 00 00 ]
( st* count* -- )
&add
STH2
( st* : count* )
DUP2 ;&addr JSR2
( st* pagenum offset : count* )
DUP4 ;&add/count ROT2 ROT2 ;&load JSR2
( st* pagenum offset : count* )
;&add/count STH2r ;add64 JSR2
( st* pagenum offset )
;&add/count ROT2 ROT2 ;&store JSR2
( st* )
POP2
RTN
[ &add/count COUNTPAD ]
( count* pagenum offset )
&store
COUNTSIZE ROT2 ROT2
( count* 0008 pagenum offset )
;paged-copy-to JSR2
RTN
( count* pagenum offset )
&load
COUNTSIZE ROT2 ROT2
( count* 0008 pagenum offset )
;paged-copy-from JSR2
RTN
( -- )
&dump
#0000 [ ;&dump/entrycount STA2 ]
;&dump/one ;&foreach JSR2
[ ;&dump/entrycount LDA2 ] DBGSHORTDECn POP2
RTN
[ &dump/entrycount $2 ]
( st* count* -- )
&dump/one
SWP2 ;state/print JSR2
LIT ': EMIT
;print64/no-pad JSR2
[ ;&dump/entrycount *INC2 ]
SP
RTN
( st* -- pagenum offset )
&addr
DUP2 [ STATE.score1 LDA ] #00 SWP WINSCORE MUL2 STH2
DUP2 [ STATE.score2 LDA ] #00 SWP STH2 ADD2r
COUNTSIZE STH2 MUL2r
( st* : offset )
LITr 00
DUP2 [ STATE.nextup LDA ] [ POSCOUNT POSCOUNT MUL ] MUL STH
DUP2 [ STATE.pos1 LDA ] DEC POSCOUNT MUL STH ADDr
DUP2 [ STATE.pos2 LDA ] DEC STH ADDr
( st* : pagenum offset )
POP2 STH2r STH2r
( pagenum offset )
RTN
( [ st* count* -- ] -- )
&foreach
[ ;&foreach/fn STA2 ]
#0000 #0002 DO
DUP LIT2 [ &foreach/fn $2 ] ;&nextup-foreach JSR2
LOOP
RTN
( nextup [ st* count* -- ] -- )
&nextup-foreach
[ ;&nextup-foreach/fn STA2 ]
( nextup )
[ ;&nextup-foreach/st STATE.nextup STA ]
#0000 #00 POSCOUNT DO
( pos1-1 )
DUP INC [ ;&nextup-foreach/st STATE.pos1 STA ]
#0000 #00 POSCOUNT DO
( pos1-1 pos2-1 )
DUP INC [ ;&nextup-foreach/st STATE.pos2 STA ]
OVR2 #00 POSCOUNT MUL2 OVR2 ADD2
[ ;&nextup-foreach/st STATE.nextup LDA ] [ POSCOUNT POSCOUNT MUL ] MUL #00 SWP ADD2
( pos1-1 pos2-1 pagenum )
#0000 WINSCORE DO
( pos1-1 pos2-1 pagenum score1 )
DUP [ ;&nextup-foreach/st STATE.score1 STA ]
#0000 WINSCORE DO
( pos1-1 pos2-1 pagenum score1 score2 )
DUP [ ;&nextup-foreach/st STATE.score2 STA ]
( pos1-1 pos2-1 pagenum score1 score2 )
;&nextup-foreach/st ;&addr JSR2
( pos1-1 pos2-1 pagenum score1 score2 pagenum offset )
;&nextup-foreach/count ROT2 ROT2 ;&load JSR2
( pos1-1 pos2-1 pagenum score1 score2 )
;&nextup-foreach/count ;is-non-zero64 JSR2 NOT ,&nextup-foreach/zero JCN
;&nextup-foreach/st ;&nextup-foreach/count LIT2 [ &nextup-foreach/fn $2 ] JSR2
&nextup-foreach/zero
( pos1-1 pos2-1 pagenum score1 score2 )
LOOP
LOOP
POP2
LOOP
LOOP
RTN
[ &nextup-foreach/count COUNTPAD &nextup-foreach/st STATEPAD ]
( -- count )
&count
#0000 [ ;&count/entrycount STA2 ]
;&count/one ;&foreach JSR2
[ ;&count/entrycount LDA2 ]
RTN
[ &count/entrycount $2 ]
( st* count* -- )
&count/one
POP2 POP2
[ ;&count/entrycount *INC2 ]
RTN
%PAGESIZE { #1000 } %PAGEPAD { $1000 }
~library/paging.tal
@end-of-all-things 00