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