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