new version
[Chiptunes.git] / foo.c
CommitLineData
61fab018 1#include <stdio.h>
da32ed67 2#include "fakeasm.h"
61fab018 3typedef unsigned char u8;
da32ed67 4
24abdcbb
TG
5u8 data[] = {
6 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58,
7 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
8};
61592bdd
TG
9u8 zero; //r16
10u8 acc; //r17
11u8 i0; //r18
12u8 i1; //r19
13u8 i2; //r20
14u8 i3; //r21
15u8 n; //r22
16u8 s; //r23
17u8 _; //r24
0f3f4522 18 //r25
61592bdd
TG
19u8 t;/*==Ml*/ //r26 (Xlo)
20u8 x;/*==Mh*/ //r27 (Xhi)
21 //r28
22 //r29
23/*fakestack_l*/ //r30 (Zlo)
24/*fakestack_h*/ //r31 (Zhi)
37bf20ea 25#define Mh x //mod3 vars
dbf91c38 26#define Ml t // -"-
e98ab46f 27//http://homepage.divms.uiowa.edu/~jones/bcd/mod.shtml
8d8c00e4
TG
28void mod3(void) {
29 // mod3(Mh.Ml) -> t
30 #define tmp _
5b1c6cc5
TG
31 ADD (Ml, Mh)
32 CLR (Mh)
3d517d8a
TG
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)
0e3d0279 39 ANDI (Ml, 0x0f)
2a69999d 40 ADD (Ml, tmp)
0fc1d6d3
TG
41 MOV (tmp, Ml)
42 LSR (tmp)
43 LSR (tmp)
6c72d3c1 44 ANDI (Ml, 0x03)
2a69999d
TG
45 ADD (Ml, tmp)
46 MOV (tmp, Ml)
47 LSR (tmp)
48 LSR (tmp)
49 ANDI (Ml, 0x03)
50 ADD (Ml, tmp)
c3639d5b
TG
51 CPI (Ml, 3)
52 BRPL (skip)
197a5418 53 SUBI (Ml, 3)
c3639d5b 54 skip:;
4283632d 55 RET
8d8c00e4 56 #undef tmp
e98ab46f 57}
d35c3d70
TG
58void 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:
0f3f4522 70 //TODO: directly load address to mul_* routine and jump to it?
cc428230
TG
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
d35c3d70 96 t = data[t];
cc428230
TG
97 /*MOV X_hi==x, data_hi _
98 MOV X_lo==t, data_lo \_ this won't
99 ADD X_lo, t _/ work! XXX
d35c3d70
TG
100 ADC X_hi, zero
101 LD t, X */
d0324785
TG
102 #define a1 x
103 #define a2 _
104 #define a0 t
d35c3d70 105 // start MUL
d0324785
TG
106 CLR (a2)
107 CLR (a1)
cc428230 108#endif
d0324785 109
6a1b7870 110 //sorted by ocurrence, then longest cycle count first
d35c3d70 111 CPI (t, 0x69)
44e34da0
TG
112 BREQ (mul_69)
113 CPI (t, 0x75)
114 BREQ (mul_75)
44e34da0
TG
115 CPI (t, 0x9d)
116 BREQ (mul_9d)
6a1b7870
TG
117 CPI (t, 0x58)
118 BREQ (mul_58)
119 CPI (t, 0x8c)
120 BREQ (mul_8c)
121 CPI (t, 0x84)
122 BREQ (mul_84)
44e34da0
TG
123 CPI (t, 0xb0)
124 BREQ (mul_b0)
6a1b7870 125 mul_58: // 0101 1000 (24cy)
30966f17
TG
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)
d0324785 136
30966f17
TG
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)
44e34da0 147 RJMP (endmul)
6a1b7870 148 mul_69: // 0110 1001 (26cy)
30966f17
TG
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)
d0324785 161
30966f17
TG
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)
44e34da0 172 RJMP (endmul)
6a1b7870 173 mul_75: // 0111 0101 (28cy)
30966f17
TG
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)
d0324785 186
30966f17
TG
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)
44e34da0 199 RJMP (endmul)
6a1b7870 200 mul_84: // 1000 0100 (22cy)
30966f17
TG
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)
d0324785 211
30966f17
TG
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)
44e34da0 220 RJMP (endmul)
6a1b7870 221 mul_8c: // 1000 1100 (24cy)
30966f17
TG
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)
d0324785 234
30966f17
TG
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)
44e34da0 243 RJMP (endmul)
6a1b7870 244 mul_9d: // 1001 1101 (28cy)
30966f17
TG
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)
d0324785 259
30966f17
TG
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)
44e34da0 270 RJMP (endmul)
6a1b7870 271 mul_b0: // 1011 0000 (22cy)
30966f17
TG
272 LSR (a2)
273 ROR (a1)
274 LSR (a2)
275 ROR (a1)
276 LSR (a2)
277 ROR (a1)
278 LSR (a2)
279 ROR (a1)
d0324785 280
30966f17
TG
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)
44e34da0 293 endmul:
0f3f4522
TG
294 LSR (a2) //final shift is a common operation for all
295 ROR (a1)
d0324785 296 // end MUL
0f3f4522 297 MOV (t, a1)
d0324785
TG
298 #undef a0
299 #undef a1
300 #undef a2
d5b74a12 301 RET //TODO: replace CALL/RET with IJMP?
61fab018
TG
302};
303
304int main(void) {
23e66ca4
TG
305 CLR (zero)
306 CLR (i0)
307 CLR (i1)
308 CLR (i2)
309 CLR (i3)
5dd8b8ff 310 for (;;) {
7874ed03
TG
311 MOV (n, i2)
312 LSL (n)
313 LSL (n)
8ee3310e 314 #define tmp _
bc7680e3 315 MOV (tmp, i1)
5d4207f9
TG
316 SWAP (tmp)
317 ANDI (tmp, 0x0f)
3eef1ade
TG
318 LSR (tmp)
319 LSR (tmp)
128ff01a 320 OR (n, tmp)
bc7680e3 321 #undef tmp
df192822 322 MOV (s, i3)
2bbe001f 323 LSR (s)
27b03017
TG
324 ROR (s)
325 ANDI (s, 0x80)
8ee3310e 326 #define tmp _
a582bbc3
TG
327 MOV (tmp, i2)
328 LSR (tmp)
e389879f 329 OR (s, tmp)
df192822 330 #undef tmp
3b86ca43
TG
331
332 //voice 1:
3b86ca43 333 MOV (t, n)
965274e2 334 RCALL g();
c09a6ed8 335 SWAP (t)
9e62fea4 336 ANDI (t, 1)
46a8d83c 337 MOV (acc, t)
3b86ca43
TG
338
339 //voice 2:
37bf20ea 340 #define tmp _
94c4920f
TG
341 MOV (tmp, i2)
342 LSL (tmp)
343 LSL (tmp)
344 LSL (tmp)
345 MOV (t, i1)
4b0b7dc5
TG
346 SWAP (t)
347 ANDI (t, 0xf)
348 LSR (t)
94c4920f 349 OR (t, tmp)
1b023e92 350 #undef tmp
23872091 351 EOR (t, n)
965274e2 352 RCALL g();
7716b427
TG
353 LSR (t)
354 LSR (t)
355 ANDI (t, 3)
f28def6a 356 AND (t, s)
46a8d83c 357 ADD (acc, t)
3b86ca43
TG
358
359 //voice 3:
500692e4
TG
360 MOV (Ml, i2)
361 SWAP (Ml)
362 ANDI (Ml, 0xf0)
363 LSL (Ml)
8ee3310e 364 #define tmp _
500692e4
TG
365 MOV (tmp, i1)
366 LSR (tmp)
367 LSR (tmp)
368 LSR (tmp)
369 OR (Ml, tmp)
370 #undef tmp
d39a46f5
TG
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
dbf91c38 382 RCALL mod3();
18570947 383 ADD (t, n)
965274e2 384 RCALL g();
c6c6cbe5
TG
385 LSR (t)
386 LSR (t)
387 ANDI (t, 3)
f28def6a
TG
388 MOV (x, s)
389 INC (x)
37bf20ea 390 #define tmp _
f28def6a
TG
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)
51f43293 403 AND (t, tmp)
f28def6a 404 #undef tmp
46a8d83c 405 ADD (acc, t)
3b86ca43
TG
406
407 //voice 4:
649bb224
TG
408 MOV (Ml, i2)
409 SWAP (Ml)
410 ANDI (Ml, 0xf0)
411 LSL (Ml)
412 LSL (Ml)
8ee3310e 413 #define tmp _
649bb224
TG
414 MOV (tmp, i1)
415 LSR (tmp)
416 LSR (tmp)
417 OR (Ml, tmp)
418 #undef tmp
18426c43
TG
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
dbf91c38 430 RCALL mod3();
e4f7baf0
TG
431 SUB (t, n)
432 NEG (t)
902cfdea 433 SUBI (t, -8)
965274e2 434 RCALL g();
c6c6cbe5
TG
435 LSR (t)
436 ANDI (t, 3)
9548359d 437 INC (s)
37bf20ea 438 #define tmp _
9548359d 439 MOV (tmp, s)
d8af0686 440 LSR (tmp)
9548359d 441 ADD (tmp, s)
d8af0686
TG
442 ROR (tmp)
443 LSR (tmp)
444 LSR (tmp)
9548359d 445 ADD (tmp, s)
d8af0686 446 ROR (tmp)
9548359d 447 ADD (tmp, s)
d8af0686
TG
448 ROR (tmp)
449 LSR (tmp)
450 LSR (tmp)
51f43293 451 AND (t, tmp)
d8af0686 452 #undef tmp
46a8d83c 453 ADD (acc, t)
bfce2f8c 454
95fa231f 455 putchar(acc<<4); //TODO
89f35588 456 SUBI (i0, -1)
95fa231f
TG
457 ADC (i1, zero, !i0)
458 ADC (i2, zero, !i0&&!i1)
459 ADC (i3, zero, !i0&&!i1&&!i2)
fe9a76e4 460 }
61fab018 461}
Imprint / Impressum