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