transcribe fakeasm into realasm (III)
[Chiptunes.git] / foo.S
1 /* REGISTER NAMES */
2 #define zero r16
3 #define acc r17
4 #define i0 r18
5 #define i1 r19
6 #define i2 r20
7 #define i3 r21
8 #define n r22
9 #define s r23
10 #define _ r24
11 ; r25
12 #define x r26 //==Xlo==Mh
13 #define t r27 //==Xhi==Ml
14 ; r28
15 ; r29
16 ; r30 Zlo
17 ; r31 Zhi
18 ; aliases:
19 #define Xlo r26
20 #define Xhi r27
21 #define Mh r26 //mod3 vars
22 #define Ml r27 // -"-
23
24 /* I/O REGISTERS */
25 OCR0AL = 0x26
26 DDRB = 0x01
27 PUEB = 0x03
28 SPL = 0x3D
29 SPH = 0x3E
30 CCP = 0x3C
31 CLKPSR = 0x36
32 SMCR = 0x3A
33 TCCR0A = 0x2E
34 TCCR0B = 0x2D
35 TIMSK0 = 0x2B
36 TIFR0 = 0x2A
37
38 .section .data
39 .byte 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58
40 .byte 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
41
42 .section .text
43
44 mod3: ; mod3(Mh.Ml) -> t
45 #define tmp _
46 ADD Ml, Mh
47 CLR Mh
48 ADC Mh, zero
49 MOV tmp, Ml
50 SWAP tmp
51 ANDI tmp, 0x0f
52 SWAP Mh
53 OR tmp, Mh
54 ANDI Ml, 0x0f
55 ADD Ml, tmp
56 MOV tmp, Ml
57 LSR tmp
58 LSR tmp
59 ANDI Ml, 0x03
60 ADD Ml, tmp
61 MOV tmp, Ml
62 LSR tmp
63 LSR tmp
64 ANDI Ml, 0x03
65 ADD Ml, tmp
66 CPI Ml, 3
67 BRPL skip
68 SUBI Ml, 3
69 skip:
70 RET
71 #undef tmp
72
73 ; definitions to mul-tree readable:
74 .macro always _bit ; nop; for when a test() is not necessary (see tree)
75 .endm
76 .macro never _bit ; nop; for when a test() is not necessary (see tree)
77 .endm
78 .macro test _bit,_jmpto
79 SBRC t, _bit
80 RJMP _jmpto
81 .endm
82 .macro shift16
83 LSR a2
84 ROR a1
85 .endm
86 .macro shift8 ; top three bits don't need to be corrrect, so save cycles by not carrying
87 LSR a1
88 .endm
89 .macro shift0 ; nop; last shift is common
90 .endm
91 .macro add_shift16
92 ADD a1, i0
93 ADC a2, i1
94 shift16
95 .endm
96 .macro add_shift8 ; ditto with carrying
97 ADD a1, i0
98 shift8
99 .endm
100 .macro add_shift0 ; last shift is common
101 ADD a1, i0
102 .endm
103
104 g: ; g(i, t) -> t
105 #define tmp _
106 ANDI t, 0x07
107 MOV tmp, i2
108 ANDI tmp, 3
109 TST tmp
110 CPSE tmp, zero
111 SUBI t, -8
112 #undef tmp
113
114 #define tmp _
115 MOV tmp, t ; NOTE: must move value away from `t`, as that is also hi(X)
116 LDI Xhi, hi8(data) ; TODO: can skip if &data < 0xff (it is)
117 LDI Xlo, lo8(data)
118 ADD Xlo, tmp ;<-- the offset (formerly `t`) into data[]
119 ADC Xhi, zero ; ditto skip
120 LD tmp, X
121 MOV t, tmp
122 #undef tmp
123
124 #define a1 x
125 #define a2 _
126 #define a0 t
127 CLR a2
128 CLR a1
129
130 /* decision tree multiplication saves cycles and (hopefully) reduces code size
131 _xxx?
132 / \
133 _xx?0 _xx1?
134 | |
135 _x?00 _x?01
136 / \ / \
137 _?000 _?100 _?001 _?101
138 / \ / \ | / \
139 _0000 _1000 _0100 _1100 _1001 _0101 _1101
140 | | | | | | |
141 ... ... ... ... ... ... ...
142 | | | | | | |
143 B0 58 84 8C 69 75 9D */
144 test 0, m____1
145 m____0: shift16
146 never 1
147 m___00: shift16
148 test 2, m__100
149 m__000: shift16
150 test 3, m_1000
151 m_0000: shift16
152 always 4
153 add_shift16
154 always 5
155 add_shift8
156 never 6
157 shift8
158 always 7
159 add_shift0
160 RJMP end_mul ; calc'd 0xb0
161
162 m_1000: add_shift16
163 always 4
164 add_shift16
165 never 5
166 shift8
167 always 6
168 add_shift8
169 never 7
170 shift0
171 RJMP end_mul ; calc'd 0x58
172
173 m__100: add_shift16
174 test 3, m_1100
175 m_0100: shift16
176 RJMP upper_8 ;'ll calc 0x84
177
178 m_1100: add_shift16
179 upper_8: ; used twice, so deduplicated
180 never 4
181 shift16
182 never 5
183 shift8
184 never 6
185 shift8
186 always 7
187 add_shift0
188 RJMP end_mul ; calc'd 0x8c
189
190 m____1: add_shift16
191 never 1
192 m___01: shift16
193 test 2, m__101
194 m__001: shift16
195 always 3
196 m_1001: add_shift16
197 never 4
198 shift16
199 always 5
200 add_shift8
201 always 6
202 add_shift8
203 never 7
204 shift0
205 RJMP end_mul ; calc'd 0x69
206
207 m__101: add_shift16
208 test 3, m_1101
209 m_0101: shift16
210 always 4
211 add_shift16
212 always 5
213 add_shift8
214 always 6
215 add_shift8
216 never 7
217 shift0
218 RJMP end_mul ; calc'd 0x75
219
220 m_1101: add_shift16
221 always 4
222 add_shift16
223 never 5
224 shift8
225 never 6
226 shift8
227 always 7
228 add_shift0
229 ; calc'd 0x9d
230
231 end_mul:
232 LSR a1 ;final shift is a common operation for all
233
234 MOV t, a1 ;;TODO: use a1 in main() directly
235 #undef a0
236 #undef a1
237 #undef a2
238 RET ; TODO: replace CALL/RET with IJMP?
239
240 main:
241 CLR zero
242 CLR i0
243 CLR i1
244 CLR i2
245 CLR i3
246 ;;TODO: setup stack pointer, portb, clock, sleep mode, timer0
247 RJMP sample
248 sample: ;;TODO: this will probably become the timer0 overflow interrupt handler
249 MOV n, i2
250 LSL n
251 LSL n
252 #define tmp _
253 MOV tmp, i1
254 SWAP tmp
255 ANDI tmp, 0x0f
256 LSR tmp
257 LSR tmp
258 OR n, tmp
259 #undef tmp
260 MOV s, i3
261 LSR s
262 ROR s
263 ANDI s, 0x80
264 #define tmp _
265 MOV tmp, i2
266 LSR tmp
267 OR s, tmp
268 #undef tmp
269
270 ; voice 1:
271 MOV t, n
272 RCALL g
273 SWAP t
274 ANDI t, 1
275 MOV acc, t
276
277 ; voice 2:
278 #define tmp _
279 MOV tmp, i2
280 LSL tmp
281 LSL tmp
282 LSL tmp
283 MOV t, i1
284 SWAP t
285 ANDI t, 0xf
286 LSR t
287 OR t, tmp
288 #undef tmp
289 EOR t, n
290 RCALL g
291 LSR t
292 LSR t
293 ANDI t, 3
294 AND t, s
295 ADD acc, t
296
297 ; voice 3:
298 MOV Ml, i2
299 SWAP Ml
300 ANDI Ml, 0xf0
301 LSL Ml
302 #define tmp _
303 MOV tmp, i1
304 LSR tmp
305 LSR tmp
306 LSR tmp
307 OR Ml, tmp
308 #undef tmp
309 MOV Mh, i3
310 SWAP Mh
311 ANDI Mh, 0xf0
312 LSL Mh
313 #define tmp _
314 MOV tmp, i2
315 LSR tmp
316 LSR tmp
317 LSR tmp
318 OR Mh, tmp
319 #undef tmp
320 RCALL mod3
321 ADD t, n
322 RCALL g
323 LSR t
324 LSR t
325 ANDI t, 3
326 MOV x, s
327 INC x
328 #define tmp _
329 MOV tmp, x
330 LSR tmp
331 LSR tmp
332 ADD tmp, x
333 ROR tmp
334 LSR tmp
335 ADD tmp, x
336 ROR tmp
337 LSR tmp
338 ADD tmp, x
339 ROR tmp
340 LSR tmp
341 AND t, tmp
342 #undef tmp
343 ADD acc, t
344
345 ; voice 4:
346 MOV Ml, i2
347 SWAP Ml
348 ANDI Ml, 0xf0
349 LSL Ml
350 LSL Ml
351 #define tmp _
352 MOV tmp, i1
353 LSR tmp
354 LSR tmp
355 OR Ml, tmp
356 #undef tmp
357 MOV Mh, i3
358 SWAP Mh
359 ANDI Mh, 0xf0
360 LSL Mh
361 LSL Mh
362 #define tmp _
363 MOV tmp, i2
364 LSR tmp
365 LSR tmp
366 OR Mh, tmp
367 #undef tmp
368 RCALL mod3
369 SUB t, n
370 NEG t
371 SUBI t, -8
372 RCALL g
373 LSR t
374 ANDI t, 3
375 INC s
376 #define tmp _
377 MOV tmp, s
378 LSR tmp
379 ADD tmp, s
380 ROR tmp
381 LSR tmp
382 LSR tmp
383 ADD tmp, s
384 ROR tmp
385 ADD tmp, s
386 ROR tmp
387 LSR tmp
388 LSR tmp
389 AND t, tmp
390 #undef tmp
391 ADD acc, t
392
393 SWAP acc
394 OUT OCR0AL, acc
395 SUBI i0, -1
396 SBCI i1, -1
397 SBCI i2, -1
398 SBCI i3, -1
399
400 rjmp sample ;;TODO: -> RETI
Imprint / Impressum