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 u8 loop; //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 mul(void) { //don't need overhead of function (inline it)
59 // i1.i0 * t -> _.x.t
60 #define a1 x
61 #define a2 _
62 #define a0 t
63 // start MUL -- 92 cycles :( (unrolled and skipping second bit: 76)
64 CLR (a2)
65 CLR (a1)
66
67 CPI (t, 0x58)
68 BREQ (mul_58)
69 CPI (t, 0x69)
70 BREQ (mul_69)
71 CPI (t, 0x75)
72 BREQ (mul_75)
73 CPI (t, 0x84)
74 BREQ (mul_84)
75 CPI (t, 0x8c)
76 BREQ (mul_8c)
77 CPI (t, 0x9d)
78 BREQ (mul_9d)
79 CPI (t, 0xb0)
80 BREQ (mul_b0)
81 mul_58: // 0101 1000
82 LSR (a2)
83 ROR (a1)
84 LSR (a2)
85 ROR (a1)
86 LSR (a2)
87 ROR (a1)
88 ADD (a1, i0)
89 ADC (a2, i1, carry)
90 LSR (a2)
91 ROR (a1)
92
93 ADD (a1, i0)
94 ADC (a2, i1, carry)
95 LSR (a2)
96 ROR (a1)
97 LSR (a2)
98 ROR (a1)
99 ADD (a1, i0)
100 ADC (a2, i1, carry)
101 LSR (a2)
102 ROR (a1)
103 LSR (a2)
104 ROR (a1)
105 RJMP (endmul)
106 mul_69: // 0110 1001
107 ADD (a1, i0)
108 ADC (a2, i1, carry)
109 LSR (a2)
110 ROR (a1)
111 LSR (a2)
112 ROR (a1)
113 LSR (a2)
114 ROR (a1)
115 ADD (a1, i0)
116 ADC (a2, i1, carry)
117 LSR (a2)
118 ROR (a1)
119
120 LSR (a2)
121 ROR (a1)
122 ADD (a1, i0)
123 ADC (a2, i1, carry)
124 LSR (a2)
125 ROR (a1)
126 ADD (a1, i0)
127 ADC (a2, i1, carry)
128 LSR (a2)
129 ROR (a1)
130 LSR (a2)
131 ROR (a1)
132 RJMP (endmul)
133 mul_75: // 0111 0101
134 ADD (a1, i0)
135 ADC (a2, i1, carry)
136 LSR (a2)
137 ROR (a1)
138 LSR (a2)
139 ROR (a1)
140 ADD (a1, i0)
141 ADC (a2, i1, carry)
142 LSR (a2)
143 ROR (a1)
144 LSR (a2)
145 ROR (a1)
146
147 ADD (a1, i0)
148 ADC (a2, i1, carry)
149 LSR (a2)
150 ROR (a1)
151 ADD (a1, i0)
152 ADC (a2, i1, carry)
153 LSR (a2)
154 ROR (a1)
155 ADD (a1, i0)
156 ADC (a2, i1, carry)
157 LSR (a2)
158 ROR (a1)
159 LSR (a2)
160 ROR (a1)
161 RJMP (endmul)
162 mul_84: // 1000 0100
163 LSR (a2)
164 ROR (a1)
165 LSR (a2)
166 ROR (a1)
167 ADD (a1, i0)
168 ADC (a2, i1, carry)
169 LSR (a2)
170 ROR (a1)
171 LSR (a2)
172 ROR (a1)
173
174 LSR (a2)
175 ROR (a1)
176 LSR (a2)
177 ROR (a1)
178 LSR (a2)
179 ROR (a1)
180 ADD (a1, i0)
181 ADC (a2, i1, carry)
182 LSR (a2)
183 ROR (a1)
184 RJMP (endmul)
185 mul_8c: // 1000 1100
186 LSR (a2)
187 ROR (a1)
188 LSR (a2)
189 ROR (a1)
190 ADD (a1, i0)
191 ADC (a2, i1, carry)
192 LSR (a2)
193 ROR (a1)
194 ADD (a1, i0)
195 ADC (a2, i1, carry)
196 LSR (a2)
197 ROR (a1)
198
199 LSR (a2)
200 ROR (a1)
201 LSR (a2)
202 ROR (a1)
203 LSR (a2)
204 ROR (a1)
205 ADD (a1, i0)
206 ADC (a2, i1, carry)
207 LSR (a2)
208 ROR (a1)
209 RJMP (endmul)
210 mul_9d: // 1001 1101
211 ADD (a1, i0)
212 ADC (a2, i1, carry)
213 LSR (a2)
214 ROR (a1)
215 LSR (a2)
216 ROR (a1)
217 ADD (a1, i0)
218 ADC (a2, i1, carry)
219 LSR (a2)
220 ROR (a1)
221 ADD (a1, i0)
222 ADC (a2, i1, carry)
223 LSR (a2)
224 ROR (a1)
225
226 ADD (a1, i0)
227 ADC (a2, i1, carry)
228 LSR (a2)
229 ROR (a1)
230 LSR (a2)
231 ROR (a1)
232 LSR (a2)
233 ROR (a1)
234 ADD (a1, i0)
235 ADC (a2, i1, carry)
236 LSR (a2)
237 ROR (a1)
238 RJMP (endmul)
239 mul_b0: // 1011 0000
240 LSR (a2)
241 ROR (a1)
242 LSR (a2)
243 ROR (a1)
244 LSR (a2)
245 ROR (a1)
246 LSR (a2)
247 ROR (a1)
248
249 ADD (a1, i0)
250 ADC (a2, i1, carry)
251 LSR (a2)
252 ROR (a1)
253 ADD (a1, i0)
254 ADC (a2, i1, carry)
255 LSR (a2)
256 ROR (a1)
257 LSR (a2)
258 ROR (a1)
259 ADD (a1, i0)
260 ADC (a2, i1, carry)
261 LSR (a2)
262 ROR (a1)
263 endmul:
264
265 // end MUL
266 #undef a0
267 #undef a1
268 #undef a2
269 RET
270 }
271 void g(void) {
272 // g(i, t) -> t
273 // tempvars: `x` and `_`
274 #define tmp _
275 ANDI (t, 0x07)
276 MOV (tmp, i2)
277 ANDI (tmp, 3)
278 TST (tmp)
279 #undef tmp
280 BREQ (skip)
281 SUBI (t, -8)
282 skip:
283 t = data[t];
284 /*MOV X_hi==x, data_hi
285 MOV X_lo==t, data_lo
286 ADD X_lo, t
287 ADC X_hi, zero
288 LD t, X */
289 RCALL mul(); //stores used value in in x
290 MOV (t, x)
291 RET //TODO: replace CALL/RET with IJMP?
292 };
293
294 int main(void) {
295 CLR (zero)
296 CLR (i0)
297 CLR (i1)
298 CLR (i2)
299 CLR (i3)
300 for (;;) {
301 MOV (n, i2)
302 LSL (n)
303 LSL (n)
304 #define tmp _
305 MOV (tmp, i1)
306 SWAP (tmp)
307 ANDI (tmp, 0x0f)
308 LSR (tmp)
309 LSR (tmp)
310 OR (n, tmp)
311 #undef tmp
312 MOV (s, i3)
313 LSR (s)
314 ROR (s)
315 ANDI (s, 0x80)
316 #define tmp _
317 MOV (tmp, i2)
318 LSR (tmp)
319 OR (s, tmp)
320 #undef tmp
321
322 //voice 1:
323 MOV (t, n)
324 RCALL g();
325 SWAP (t)
326 ANDI (t, 1)
327 MOV (acc, t)
328
329 //voice 2:
330 #define tmp _
331 MOV (tmp, i2)
332 LSL (tmp)
333 LSL (tmp)
334 LSL (tmp)
335 MOV (t, i1)
336 SWAP (t)
337 ANDI (t, 0xf)
338 LSR (t)
339 OR (t, tmp)
340 #undef tmp
341 EOR (t, n)
342 RCALL g();
343 LSR (t)
344 LSR (t)
345 ANDI (t, 3)
346 AND (t, s)
347 ADD (acc, t)
348
349 //voice 3:
350 MOV (Ml, i2)
351 SWAP (Ml)
352 ANDI (Ml, 0xf0)
353 LSL (Ml)
354 #define tmp _
355 MOV (tmp, i1)
356 LSR (tmp)
357 LSR (tmp)
358 LSR (tmp)
359 OR (Ml, tmp)
360 #undef tmp
361 MOV (Mh, i3)
362 SWAP (Mh)
363 ANDI (Mh, 0xf0)
364 LSL (Mh)
365 #define tmp _
366 MOV (tmp, i2)
367 LSR (tmp)
368 LSR (tmp)
369 LSR (tmp)
370 OR (Mh, tmp)
371 #undef tmp
372 RCALL mod3();
373 ADD (t, n)
374 RCALL g();
375 LSR (t)
376 LSR (t)
377 ANDI (t, 3)
378 MOV (x, s)
379 INC (x)
380 #define tmp _
381 MOV (tmp, x)
382 LSR (tmp)
383 LSR (tmp)
384 ADD (tmp, x)
385 ROR (tmp)
386 LSR (tmp)
387 ADD (tmp, x)
388 ROR (tmp)
389 LSR (tmp)
390 ADD (tmp, x)
391 ROR (tmp)
392 LSR (tmp)
393 AND (t, tmp)
394 #undef tmp
395 ADD (acc, t)
396
397 //voice 4:
398 MOV (Ml, i2)
399 SWAP (Ml)
400 ANDI (Ml, 0xf0)
401 LSL (Ml)
402 LSL (Ml)
403 #define tmp _
404 MOV (tmp, i1)
405 LSR (tmp)
406 LSR (tmp)
407 OR (Ml, tmp)
408 #undef tmp
409 MOV (Mh, i3)
410 SWAP (Mh)
411 ANDI (Mh, 0xf0)
412 LSL (Mh)
413 LSL (Mh)
414 #define tmp _
415 MOV (tmp, i2)
416 LSR (tmp)
417 LSR (tmp)
418 OR (Mh, tmp)
419 #undef tmp
420 RCALL mod3();
421 SUB (t, n)
422 NEG (t)
423 SUBI (t, -8)
424 RCALL g();
425 LSR (t)
426 ANDI (t, 3)
427 INC (s)
428 #define tmp _
429 MOV (tmp, s)
430 LSR (tmp)
431 ADD (tmp, s)
432 ROR (tmp)
433 LSR (tmp)
434 LSR (tmp)
435 ADD (tmp, s)
436 ROR (tmp)
437 ADD (tmp, s)
438 ROR (tmp)
439 LSR (tmp)
440 LSR (tmp)
441 AND (t, tmp)
442 #undef tmp
443 ADD (acc, t)
444
445 putchar(acc<<4); //TODO
446 SUBI (i0, -1)
447 ADC (i1, zero, !i0)
448 ADC (i2, zero, !i0&&!i1)
449 ADC (i3, zero, !i0&&!i1&&!i2)
450 }
451 }
Imprint / Impressum