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 #define MUL_ADD_ROR \
68 ADD (a1, i0) \
69 ADC (a2, i1, carry) \
70 MUL_ROR
71
72 #define MUL_ROR \
73 LSR (a2) \
74 ROR (a1) \
75 ROR (t) //superfluous?
76
77 switch(t) {
78 case 0x58: // 0101 1000
79 MUL_ROR
80 MUL_ROR
81 MUL_ROR
82 MUL_ADD_ROR
83
84 MUL_ADD_ROR
85 MUL_ROR
86 MUL_ADD_ROR
87 MUL_ROR
88 break;
89 case 0x69: // 0110 1001
90 MUL_ADD_ROR
91 MUL_ROR
92 MUL_ROR
93 MUL_ADD_ROR
94
95 MUL_ROR
96 MUL_ADD_ROR
97 MUL_ADD_ROR
98 MUL_ROR
99 break;
100 case 0x75: // 0111 0101
101 MUL_ADD_ROR
102 MUL_ROR
103 MUL_ADD_ROR
104 MUL_ROR
105
106 MUL_ADD_ROR
107 MUL_ADD_ROR
108 MUL_ADD_ROR
109 MUL_ROR
110 break;
111 case 0x84: // 1000 0100
112 MUL_ROR
113 MUL_ROR
114 MUL_ADD_ROR
115 MUL_ROR
116
117 MUL_ROR
118 MUL_ROR
119 MUL_ROR
120 MUL_ADD_ROR
121 break;
122 case 0x8c: // 1000 1100
123 MUL_ROR
124 MUL_ROR
125 MUL_ADD_ROR
126 MUL_ADD_ROR
127
128 MUL_ROR
129 MUL_ROR
130 MUL_ROR
131 MUL_ADD_ROR
132 break;
133 case 0x9d: // 1001 1101
134 MUL_ADD_ROR
135 MUL_ROR
136 MUL_ADD_ROR
137 MUL_ADD_ROR
138
139 MUL_ADD_ROR
140 MUL_ROR
141 MUL_ROR
142 MUL_ADD_ROR
143 break;
144 case 0xb0: // 1011 0000
145 MUL_ROR
146 MUL_ROR
147 MUL_ROR
148 MUL_ROR
149
150 MUL_ADD_ROR
151 MUL_ADD_ROR
152 MUL_ROR
153 MUL_ADD_ROR
154 }
155
156 // end MUL
157 #undef a0
158 #undef a1
159 #undef a2
160 RET
161 }
162 void g(void) {
163 // g(i, t) -> t
164 // tempvars: `x` and `_`
165 #define tmp _
166 ANDI (t, 0x07)
167 MOV (tmp, i2)
168 ANDI (tmp, 3)
169 TST (tmp)
170 #undef tmp
171 BREQ (skip)
172 SUBI (t, -8)
173 skip:
174 t = data[t];
175 /*MOV X_hi==x, data_hi
176 MOV X_lo==t, data_lo
177 ADD X_lo, t
178 ADC X_hi, zero
179 LD t, X */
180 RCALL mul(); //stores used value in in x
181 MOV (t, x)
182 RET //TODO: replace CALL/RET with IJMP?
183 };
184
185 int main(void) {
186 CLR (zero)
187 CLR (i0)
188 CLR (i1)
189 CLR (i2)
190 CLR (i3)
191 for (;;) {
192 MOV (n, i2)
193 LSL (n)
194 LSL (n)
195 #define tmp _
196 MOV (tmp, i1)
197 SWAP (tmp)
198 ANDI (tmp, 0x0f)
199 LSR (tmp)
200 LSR (tmp)
201 OR (n, tmp)
202 #undef tmp
203 MOV (s, i3)
204 LSR (s)
205 ROR (s)
206 ANDI (s, 0x80)
207 #define tmp _
208 MOV (tmp, i2)
209 LSR (tmp)
210 OR (s, tmp)
211 #undef tmp
212
213 //voice 1:
214 MOV (t, n)
215 RCALL g();
216 SWAP (t)
217 ANDI (t, 1)
218 MOV (acc, t)
219
220 //voice 2:
221 #define tmp _
222 MOV (tmp, i2)
223 LSL (tmp)
224 LSL (tmp)
225 LSL (tmp)
226 MOV (t, i1)
227 SWAP (t)
228 ANDI (t, 0xf)
229 LSR (t)
230 OR (t, tmp)
231 #undef tmp
232 EOR (t, n)
233 RCALL g();
234 LSR (t)
235 LSR (t)
236 ANDI (t, 3)
237 AND (t, s)
238 ADD (acc, t)
239
240 //voice 3:
241 MOV (Ml, i2)
242 SWAP (Ml)
243 ANDI (Ml, 0xf0)
244 LSL (Ml)
245 #define tmp _
246 MOV (tmp, i1)
247 LSR (tmp)
248 LSR (tmp)
249 LSR (tmp)
250 OR (Ml, tmp)
251 #undef tmp
252 MOV (Mh, i3)
253 SWAP (Mh)
254 ANDI (Mh, 0xf0)
255 LSL (Mh)
256 #define tmp _
257 MOV (tmp, i2)
258 LSR (tmp)
259 LSR (tmp)
260 LSR (tmp)
261 OR (Mh, tmp)
262 #undef tmp
263 RCALL mod3();
264 ADD (t, n)
265 RCALL g();
266 LSR (t)
267 LSR (t)
268 ANDI (t, 3)
269 MOV (x, s)
270 INC (x)
271 #define tmp _
272 MOV (tmp, x)
273 LSR (tmp)
274 LSR (tmp)
275 ADD (tmp, x)
276 ROR (tmp)
277 LSR (tmp)
278 ADD (tmp, x)
279 ROR (tmp)
280 LSR (tmp)
281 ADD (tmp, x)
282 ROR (tmp)
283 LSR (tmp)
284 AND (t, tmp)
285 #undef tmp
286 ADD (acc, t)
287
288 //voice 4:
289 MOV (Ml, i2)
290 SWAP (Ml)
291 ANDI (Ml, 0xf0)
292 LSL (Ml)
293 LSL (Ml)
294 #define tmp _
295 MOV (tmp, i1)
296 LSR (tmp)
297 LSR (tmp)
298 OR (Ml, tmp)
299 #undef tmp
300 MOV (Mh, i3)
301 SWAP (Mh)
302 ANDI (Mh, 0xf0)
303 LSL (Mh)
304 LSL (Mh)
305 #define tmp _
306 MOV (tmp, i2)
307 LSR (tmp)
308 LSR (tmp)
309 OR (Mh, tmp)
310 #undef tmp
311 RCALL mod3();
312 SUB (t, n)
313 NEG (t)
314 SUBI (t, -8)
315 RCALL g();
316 LSR (t)
317 ANDI (t, 3)
318 INC (s)
319 #define tmp _
320 MOV (tmp, s)
321 LSR (tmp)
322 ADD (tmp, s)
323 ROR (tmp)
324 LSR (tmp)
325 LSR (tmp)
326 ADD (tmp, s)
327 ROR (tmp)
328 ADD (tmp, s)
329 ROR (tmp)
330 LSR (tmp)
331 LSR (tmp)
332 AND (t, tmp)
333 #undef tmp
334 ADD (acc, t)
335
336 putchar(acc<<4); //TODO
337 SUBI (i0, -1)
338 ADC (i1, zero, !i0)
339 ADC (i2, zero, !i0&&!i1)
340 ADC (i3, zero, !i0&&!i1&&!i2)
341 }
342 }
Imprint / Impressum