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