new version
[Chiptunes.git] / foo.c
1 #include <stdio.h>
2 #include "fakeasm.h"
3 typedef unsigned char u8;
4
5 u8 data[] = {
6 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58,
7 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
8 };
9 u8 zero; //r16
10 u8 acc; //r17
11 u8 i0; //r18
12 u8 i1; //r19
13 u8 i2; //r20
14 u8 i3; //r21
15 u8 n; //r22
16 u8 s; //r23
17 u8 _; //r24
18 //r25
19 u8 t;/*==Ml*/ //r26 (Xlo)
20 u8 x;/*==Mh*/ //r27 (Xhi)
21 //r28
22 //r29
23 /*fakestack_l*/ //r30 (Zlo)
24 /*fakestack_h*/ //r31 (Zhi)
25 #define Mh x //mod3 vars
26 #define Ml t // -"-
27 //http://homepage.divms.uiowa.edu/~jones/bcd/mod.shtml
28 void mod3(void) {
29 // mod3(Mh.Ml) -> t
30 #define tmp _
31 ADD (Ml, Mh)
32 CLR (Mh)
33 ADC (Mh, zero, carry) //Mh only holds the carry bit
34 MOV (tmp, Ml)
35 SWAP (tmp)
36 ANDI (tmp, 0x0f)
37 SWAP (Mh)
38 OR (tmp, Mh)
39 ANDI (Ml, 0x0f)
40 ADD (Ml, tmp)
41 MOV (tmp, Ml)
42 LSR (tmp)
43 LSR (tmp)
44 ANDI (Ml, 0x03)
45 ADD (Ml, tmp)
46 MOV (tmp, Ml)
47 LSR (tmp)
48 LSR (tmp)
49 ANDI (Ml, 0x03)
50 ADD (Ml, tmp)
51 CPI (Ml, 3)
52 BRPL (skip)
53 SUBI (Ml, 3)
54 skip:;
55 RET
56 #undef tmp
57 }
58 void g(void) {
59 // g(i, t) -> t
60 // tempvars: `x` and `_`
61 #define tmp _
62 ANDI (t, 0x07)
63 MOV (tmp, i2)
64 ANDI (tmp, 3)
65 TST (tmp)
66 #undef tmp
67 BREQ (skip)
68 SUBI (t, -8)
69 skip:
70 //TODO: directly load address to mul_* routine and jump to it?
71 t = data[t];
72 /*MOV X_hi==x, data_hi
73 MOV X_lo==t, data_lo
74 ADD X_lo, t
75 ADC X_hi, zero
76 LD t, X */
77 #define a1 x
78 #define a2 _
79 #define a0 t
80 // start MUL
81 CLR (a2)
82 CLR (a1)
83
84 //sorted by ocurrence, then longest cycle count first
85 CPI (t, 0x69)
86 BREQ (mul_69)
87 CPI (t, 0x75)
88 BREQ (mul_75)
89 CPI (t, 0x9d)
90 BREQ (mul_9d)
91 CPI (t, 0x58)
92 BREQ (mul_58)
93 CPI (t, 0x8c)
94 BREQ (mul_8c)
95 CPI (t, 0x84)
96 BREQ (mul_84)
97 CPI (t, 0xb0)
98 BREQ (mul_b0)
99 mul_58: // 0101 1000 (24cy)
100 LSR (a2)
101 ROR (a1)
102 LSR (a2)
103 ROR (a1)
104 LSR (a2)
105 ROR (a1)
106 ADD (a1, i0)
107 ADC (a2, i1, carry)
108 LSR (a2)
109 ROR (a1)
110
111 ADD (a1, i0)
112 ADC (a2, i1, carry)
113 LSR (a2)
114 ROR (a1)
115 LSR (a2)
116 ROR (a1)
117 ADD (a1, i0)
118 ADC (a2, i1, carry)
119 LSR (a2)
120 ROR (a1)
121 RJMP (endmul)
122 mul_69: // 0110 1001 (26cy)
123 ADD (a1, i0)
124 ADC (a2, i1, carry)
125 LSR (a2)
126 ROR (a1)
127 LSR (a2)
128 ROR (a1)
129 LSR (a2)
130 ROR (a1)
131 ADD (a1, i0)
132 ADC (a2, i1, carry)
133 LSR (a2)
134 ROR (a1)
135
136 LSR (a2)
137 ROR (a1)
138 ADD (a1, i0)
139 ADC (a2, i1, carry)
140 LSR (a2)
141 ROR (a1)
142 ADD (a1, i0)
143 ADC (a2, i1, carry)
144 LSR (a2)
145 ROR (a1)
146 RJMP (endmul)
147 mul_75: // 0111 0101 (28cy)
148 ADD (a1, i0)
149 ADC (a2, i1, carry)
150 LSR (a2)
151 ROR (a1)
152 LSR (a2)
153 ROR (a1)
154 ADD (a1, i0)
155 ADC (a2, i1, carry)
156 LSR (a2)
157 ROR (a1)
158 LSR (a2)
159 ROR (a1)
160
161 ADD (a1, i0)
162 ADC (a2, i1, carry)
163 LSR (a2)
164 ROR (a1)
165 ADD (a1, i0)
166 ADC (a2, i1, carry)
167 LSR (a2)
168 ROR (a1)
169 ADD (a1, i0)
170 ADC (a2, i1, carry)
171 LSR (a2)
172 ROR (a1)
173 RJMP (endmul)
174 mul_84: // 1000 0100 (22cy)
175 LSR (a2)
176 ROR (a1)
177 LSR (a2)
178 ROR (a1)
179 ADD (a1, i0)
180 ADC (a2, i1, carry)
181 LSR (a2)
182 ROR (a1)
183 LSR (a2)
184 ROR (a1)
185
186 LSR (a2)
187 ROR (a1)
188 LSR (a2)
189 ROR (a1)
190 LSR (a2)
191 ROR (a1)
192 ADD (a1, i0)
193 ADC (a2, i1, carry)
194 RJMP (endmul)
195 mul_8c: // 1000 1100 (24cy)
196 LSR (a2)
197 ROR (a1)
198 LSR (a2)
199 ROR (a1)
200 ADD (a1, i0)
201 ADC (a2, i1, carry)
202 LSR (a2)
203 ROR (a1)
204 ADD (a1, i0)
205 ADC (a2, i1, carry)
206 LSR (a2)
207 ROR (a1)
208
209 LSR (a2)
210 ROR (a1)
211 LSR (a2)
212 ROR (a1)
213 LSR (a2)
214 ROR (a1)
215 ADD (a1, i0)
216 ADC (a2, i1, carry)
217 RJMP (endmul)
218 mul_9d: // 1001 1101 (28cy)
219 ADD (a1, i0)
220 ADC (a2, i1, carry)
221 LSR (a2)
222 ROR (a1)
223 LSR (a2)
224 ROR (a1)
225 ADD (a1, i0)
226 ADC (a2, i1, carry)
227 LSR (a2)
228 ROR (a1)
229 ADD (a1, i0)
230 ADC (a2, i1, carry)
231 LSR (a2)
232 ROR (a1)
233
234 ADD (a1, i0)
235 ADC (a2, i1, carry)
236 LSR (a2)
237 ROR (a1)
238 LSR (a2)
239 ROR (a1)
240 LSR (a2)
241 ROR (a1)
242 ADD (a1, i0)
243 ADC (a2, i1, carry)
244 RJMP (endmul)
245 mul_b0: // 1011 0000 (22cy)
246 LSR (a2)
247 ROR (a1)
248 LSR (a2)
249 ROR (a1)
250 LSR (a2)
251 ROR (a1)
252 LSR (a2)
253 ROR (a1)
254
255 ADD (a1, i0)
256 ADC (a2, i1, carry)
257 LSR (a2)
258 ROR (a1)
259 ADD (a1, i0)
260 ADC (a2, i1, carry)
261 LSR (a2)
262 ROR (a1)
263 LSR (a2)
264 ROR (a1)
265 ADD (a1, i0)
266 ADC (a2, i1, carry)
267 endmul:
268 LSR (a2) //final shift is a common operation for all
269 ROR (a1)
270 // end MUL
271 MOV (t, a1)
272 #undef a0
273 #undef a1
274 #undef a2
275 RET //TODO: replace CALL/RET with IJMP?
276 };
277
278 int main(void) {
279 CLR (zero)
280 CLR (i0)
281 CLR (i1)
282 CLR (i2)
283 CLR (i3)
284 for (;;) {
285 MOV (n, i2)
286 LSL (n)
287 LSL (n)
288 #define tmp _
289 MOV (tmp, i1)
290 SWAP (tmp)
291 ANDI (tmp, 0x0f)
292 LSR (tmp)
293 LSR (tmp)
294 OR (n, tmp)
295 #undef tmp
296 MOV (s, i3)
297 LSR (s)
298 ROR (s)
299 ANDI (s, 0x80)
300 #define tmp _
301 MOV (tmp, i2)
302 LSR (tmp)
303 OR (s, tmp)
304 #undef tmp
305
306 //voice 1:
307 MOV (t, n)
308 RCALL g();
309 SWAP (t)
310 ANDI (t, 1)
311 MOV (acc, t)
312
313 //voice 2:
314 #define tmp _
315 MOV (tmp, i2)
316 LSL (tmp)
317 LSL (tmp)
318 LSL (tmp)
319 MOV (t, i1)
320 SWAP (t)
321 ANDI (t, 0xf)
322 LSR (t)
323 OR (t, tmp)
324 #undef tmp
325 EOR (t, n)
326 RCALL g();
327 LSR (t)
328 LSR (t)
329 ANDI (t, 3)
330 AND (t, s)
331 ADD (acc, t)
332
333 //voice 3:
334 MOV (Ml, i2)
335 SWAP (Ml)
336 ANDI (Ml, 0xf0)
337 LSL (Ml)
338 #define tmp _
339 MOV (tmp, i1)
340 LSR (tmp)
341 LSR (tmp)
342 LSR (tmp)
343 OR (Ml, tmp)
344 #undef tmp
345 MOV (Mh, i3)
346 SWAP (Mh)
347 ANDI (Mh, 0xf0)
348 LSL (Mh)
349 #define tmp _
350 MOV (tmp, i2)
351 LSR (tmp)
352 LSR (tmp)
353 LSR (tmp)
354 OR (Mh, tmp)
355 #undef tmp
356 RCALL mod3();
357 ADD (t, n)
358 RCALL g();
359 LSR (t)
360 LSR (t)
361 ANDI (t, 3)
362 MOV (x, s)
363 INC (x)
364 #define tmp _
365 MOV (tmp, x)
366 LSR (tmp)
367 LSR (tmp)
368 ADD (tmp, x)
369 ROR (tmp)
370 LSR (tmp)
371 ADD (tmp, x)
372 ROR (tmp)
373 LSR (tmp)
374 ADD (tmp, x)
375 ROR (tmp)
376 LSR (tmp)
377 AND (t, tmp)
378 #undef tmp
379 ADD (acc, t)
380
381 //voice 4:
382 MOV (Ml, i2)
383 SWAP (Ml)
384 ANDI (Ml, 0xf0)
385 LSL (Ml)
386 LSL (Ml)
387 #define tmp _
388 MOV (tmp, i1)
389 LSR (tmp)
390 LSR (tmp)
391 OR (Ml, tmp)
392 #undef tmp
393 MOV (Mh, i3)
394 SWAP (Mh)
395 ANDI (Mh, 0xf0)
396 LSL (Mh)
397 LSL (Mh)
398 #define tmp _
399 MOV (tmp, i2)
400 LSR (tmp)
401 LSR (tmp)
402 OR (Mh, tmp)
403 #undef tmp
404 RCALL mod3();
405 SUB (t, n)
406 NEG (t)
407 SUBI (t, -8)
408 RCALL g();
409 LSR (t)
410 ANDI (t, 3)
411 INC (s)
412 #define tmp _
413 MOV (tmp, s)
414 LSR (tmp)
415 ADD (tmp, s)
416 ROR (tmp)
417 LSR (tmp)
418 LSR (tmp)
419 ADD (tmp, s)
420 ROR (tmp)
421 ADD (tmp, s)
422 ROR (tmp)
423 LSR (tmp)
424 LSR (tmp)
425 AND (t, tmp)
426 #undef tmp
427 ADD (acc, t)
428
429 putchar(acc<<4); //TODO
430 SUBI (i0, -1)
431 ADC (i1, zero, !i0)
432 ADC (i2, zero, !i0&&!i1)
433 ADC (i3, zero, !i0&&!i1&&!i2)
434 }
435 }
Imprint / Impressum