new version
[Chiptunes.git] / foo.c
CommitLineData
61fab018 1#include <stdio.h>
da32ed67 2#include "fakeasm.h"
61fab018 3typedef unsigned char u8;
da32ed67 4
61592bdd
TG
5u8 zero; //r16
6u8 acc; //r17
7u8 i0; //r18
8u8 i1; //r19
9u8 i2; //r20
10u8 i3; //r21
11u8 n; //r22
12u8 s; //r23
13u8 _; //r24
0f3f4522 14 //r25
e8142e8f
TG
15u8 x;/*==Ml*/ //r26 (Xlo)
16u8 t;/*==Mh*/ //r27 (Xhi)
61592bdd
TG
17 //r28
18 //r29
e8142e8f
TG
19void *Z; //r30 (Zlo)
20/*...*/ //r31 (Zhi)
37bf20ea 21#define Mh x //mod3 vars
dbf91c38 22#define Ml t // -"-
e98ab46f 23//http://homepage.divms.uiowa.edu/~jones/bcd/mod.shtml
8d8c00e4
TG
24void mod3(void) {
25 // mod3(Mh.Ml) -> t
26 #define tmp _
5b1c6cc5
TG
27 ADD (Ml, Mh)
28 CLR (Mh)
3d517d8a
TG
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)
0e3d0279 35 ANDI (Ml, 0x0f)
2a69999d 36 ADD (Ml, tmp)
0fc1d6d3
TG
37 MOV (tmp, Ml)
38 LSR (tmp)
39 LSR (tmp)
6c72d3c1 40 ANDI (Ml, 0x03)
2a69999d
TG
41 ADD (Ml, tmp)
42 MOV (tmp, Ml)
43 LSR (tmp)
44 LSR (tmp)
45 ANDI (Ml, 0x03)
46 ADD (Ml, tmp)
c3639d5b
TG
47 CPI (Ml, 3)
48 BRPL (skip)
197a5418 49 SUBI (Ml, 3)
c3639d5b 50 skip:;
4283632d 51 RET
8d8c00e4 52 #undef tmp
e98ab46f 53}
d35c3d70
TG
54void g(void) {
55 // g(i, t) -> t
56 // tempvars: `x` and `_`
e8142e8f
TG
57static 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};
d35c3d70
TG
62 #define tmp _
63 ANDI (t, 0x07)
64 MOV (tmp, i2)
65 ANDI (tmp, 3)
66 TST (tmp)
02f61e33 67 CPSE (tmp, zero)
d35c3d70 68 SUBI (t, -8)
02f61e33 69 #undef tmp
cc428230
TG
70 #define a1 x
71 #define a2 _
72 #define a0 t
73 CLR (a2)
74 CLR (a1)
e8142e8f 75 goto *mul_jmptable[t]; /*
02f61e33 76 ;NOTE: optimize by placing *X and *Z below address 0xff and get rid of hi byte
e8142e8f
TG
77 LDI Xlo, lo(mul_jmptable)
78 LDI Xhi, hi(mul_jmptable)
cc428230 79 ADD Xlo, t
e8142e8f
TG
80 ADC Xhi, zero
81 ADD Xlo, t ; advance twice, since it's a 16 bit address
cc428230
TG
82 ADC Xhi, zero
83 LD Zlo, X
84 SUBI Xlo, -1
85 ADC Xhi, zero
86 LD Zhi, X
e8142e8f 87 IJMP Z */
d0324785 88
be76bfa8
TG
89 //don't care about top three bits (so don't compute them => _)
90 mul_58: // ___1 1000 (24cy)
30966f17
TG
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)
d0324785 101
30966f17
TG
102 ADD (a1, i0)
103 ADC (a2, i1, carry)
104 LSR (a2)
105 ROR (a1)
be76bfa8 106 LSR (a1)
30966f17 107 ADD (a1, i0)
be76bfa8 108 LSR (a1)
44e34da0 109 RJMP (endmul)
be76bfa8 110 mul_69: // ___0 1001 (26cy)
30966f17
TG
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)
d0324785 123
30966f17
TG
124 LSR (a2)
125 ROR (a1)
126 ADD (a1, i0)
be76bfa8 127 LSR (a1)
30966f17 128 ADD (a1, i0)
be76bfa8 129 LSR (a1)
44e34da0 130 RJMP (endmul)
be76bfa8 131 mul_75: // ___1 0101 (28cy)
30966f17
TG
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)
d0324785 144
30966f17
TG
145 ADD (a1, i0)
146 ADC (a2, i1, carry)
147 LSR (a2)
148 ROR (a1)
149 ADD (a1, i0)
be76bfa8 150 LSR (a1)
30966f17 151 ADD (a1, i0)
be76bfa8 152 LSR (a1)
44e34da0 153 RJMP (endmul)
be76bfa8 154 mul_84: // ___0 0100 (22cy)
30966f17
TG
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)
d0324785 165
30966f17
TG
166 LSR (a2)
167 ROR (a1)
be76bfa8
TG
168 LSR (a1)
169 LSR (a1)
30966f17 170 ADD (a1, i0)
44e34da0 171 RJMP (endmul)
be76bfa8 172 mul_8c: // ___0 1100 (24cy)
30966f17
TG
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)
d0324785 185
30966f17
TG
186 LSR (a2)
187 ROR (a1)
be76bfa8
TG
188 LSR (a1)
189 LSR (a1)
30966f17 190 ADD (a1, i0)
44e34da0 191 RJMP (endmul)
be76bfa8 192 mul_9d: // ___1 1101 (28cy)
30966f17
TG
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)
d0324785 207
30966f17
TG
208 ADD (a1, i0)
209 ADC (a2, i1, carry)
210 LSR (a2)
211 ROR (a1)
be76bfa8
TG
212 LSR (a1)
213 LSR (a1)
30966f17 214 ADD (a1, i0)
44e34da0 215 RJMP (endmul)
be76bfa8 216 mul_b0: // ___1 0000 (22cy)
30966f17
TG
217 LSR (a2)
218 ROR (a1)
219 LSR (a2)
220 ROR (a1)
221 LSR (a2)
222 ROR (a1)
223 LSR (a2)
224 ROR (a1)
d0324785 225
30966f17
TG
226 ADD (a1, i0)
227 ADC (a2, i1, carry)
228 LSR (a2)
229 ROR (a1)
230 ADD (a1, i0)
be76bfa8
TG
231 LSR (a1)
232 LSR (a1)
30966f17 233 ADD (a1, i0)
44e34da0 234 endmul:
be76bfa8 235 LSR (a1) //final shift is a common operation for all
d0324785 236 // end MUL
02f61e33 237 MOV (t, a1) //TODO: use a1 in main() directly
d0324785
TG
238 #undef a0
239 #undef a1
240 #undef a2
be76bfa8 241 RET //TODO: replace CALL/RET with IJMP? (requires undoing goto-mul-hack)
61fab018
TG
242};
243
244int main(void) {
23e66ca4
TG
245 CLR (zero)
246 CLR (i0)
247 CLR (i1)
248 CLR (i2)
249 CLR (i3)
5dd8b8ff 250 for (;;) {
7874ed03
TG
251 MOV (n, i2)
252 LSL (n)
253 LSL (n)
8ee3310e 254 #define tmp _
bc7680e3 255 MOV (tmp, i1)
5d4207f9
TG
256 SWAP (tmp)
257 ANDI (tmp, 0x0f)
3eef1ade
TG
258 LSR (tmp)
259 LSR (tmp)
128ff01a 260 OR (n, tmp)
bc7680e3 261 #undef tmp
df192822 262 MOV (s, i3)
2bbe001f 263 LSR (s)
27b03017
TG
264 ROR (s)
265 ANDI (s, 0x80)
8ee3310e 266 #define tmp _
a582bbc3
TG
267 MOV (tmp, i2)
268 LSR (tmp)
e389879f 269 OR (s, tmp)
df192822 270 #undef tmp
3b86ca43
TG
271
272 //voice 1:
3b86ca43 273 MOV (t, n)
965274e2 274 RCALL g();
c09a6ed8 275 SWAP (t)
9e62fea4 276 ANDI (t, 1)
46a8d83c 277 MOV (acc, t)
3b86ca43
TG
278
279 //voice 2:
37bf20ea 280 #define tmp _
94c4920f
TG
281 MOV (tmp, i2)
282 LSL (tmp)
283 LSL (tmp)
284 LSL (tmp)
285 MOV (t, i1)
4b0b7dc5
TG
286 SWAP (t)
287 ANDI (t, 0xf)
288 LSR (t)
94c4920f 289 OR (t, tmp)
1b023e92 290 #undef tmp
23872091 291 EOR (t, n)
965274e2 292 RCALL g();
7716b427
TG
293 LSR (t)
294 LSR (t)
295 ANDI (t, 3)
f28def6a 296 AND (t, s)
46a8d83c 297 ADD (acc, t)
3b86ca43
TG
298
299 //voice 3:
500692e4
TG
300 MOV (Ml, i2)
301 SWAP (Ml)
302 ANDI (Ml, 0xf0)
303 LSL (Ml)
8ee3310e 304 #define tmp _
500692e4
TG
305 MOV (tmp, i1)
306 LSR (tmp)
307 LSR (tmp)
308 LSR (tmp)
309 OR (Ml, tmp)
310 #undef tmp
d39a46f5
TG
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
dbf91c38 322 RCALL mod3();
18570947 323 ADD (t, n)
965274e2 324 RCALL g();
c6c6cbe5
TG
325 LSR (t)
326 LSR (t)
327 ANDI (t, 3)
f28def6a
TG
328 MOV (x, s)
329 INC (x)
37bf20ea 330 #define tmp _
f28def6a
TG
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)
51f43293 343 AND (t, tmp)
f28def6a 344 #undef tmp
46a8d83c 345 ADD (acc, t)
3b86ca43
TG
346
347 //voice 4:
649bb224
TG
348 MOV (Ml, i2)
349 SWAP (Ml)
350 ANDI (Ml, 0xf0)
351 LSL (Ml)
352 LSL (Ml)
8ee3310e 353 #define tmp _
649bb224
TG
354 MOV (tmp, i1)
355 LSR (tmp)
356 LSR (tmp)
357 OR (Ml, tmp)
358 #undef tmp
18426c43
TG
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
dbf91c38 370 RCALL mod3();
e4f7baf0
TG
371 SUB (t, n)
372 NEG (t)
902cfdea 373 SUBI (t, -8)
965274e2 374 RCALL g();
c6c6cbe5
TG
375 LSR (t)
376 ANDI (t, 3)
9548359d 377 INC (s)
37bf20ea 378 #define tmp _
9548359d 379 MOV (tmp, s)
d8af0686 380 LSR (tmp)
9548359d 381 ADD (tmp, s)
d8af0686
TG
382 ROR (tmp)
383 LSR (tmp)
384 LSR (tmp)
9548359d 385 ADD (tmp, s)
d8af0686 386 ROR (tmp)
9548359d 387 ADD (tmp, s)
d8af0686
TG
388 ROR (tmp)
389 LSR (tmp)
390 LSR (tmp)
51f43293 391 AND (t, tmp)
d8af0686 392 #undef tmp
46a8d83c 393 ADD (acc, t)
bfce2f8c 394
95fa231f 395 putchar(acc<<4); //TODO
89f35588 396 SUBI (i0, -1)
02f61e33
TG
397 ADC (i1, zero, !i0) //XXX: must use "sbci i1,-1" in the assembly version
398 ADC (i2, zero, !i0&&!i1) // sbci i2,-1
399 ADC (i3, zero, !i0&&!i1&&!i2) // sbci i3,-1
fe9a76e4 400 }
61fab018 401}
Imprint / Impressum