transcribe fakeasm into realasm (III)
[Chiptunes.git] / foo.S
CommitLineData
f180febe
TG
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 // -"-
da32ed67 23
f180febe
TG
24/* I/O REGISTERS */
25OCR0AL = 0x26
26DDRB = 0x01
27PUEB = 0x03
28SPL = 0x3D
29SPH = 0x3E
30CCP = 0x3C
31CLKPSR = 0x36
32SMCR = 0x3A
33TCCR0A = 0x2E
34TCCR0B = 0x2D
35TIMSK0 = 0x2B
36TIFR0 = 0x2A
4466dd8b 37
f180febe
TG
38.section .data
39 .byte 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58
40 .byte 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
4466dd8b 41
f180febe 42.section .text
4466dd8b 43
f180febe 44mod3: ; mod3(Mh.Ml) -> t
8d8c00e4 45 #define tmp _
65aa7cd6
TG
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:
4283632d 70 RET
8d8c00e4 71 #undef tmp
f180febe
TG
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
4466dd8b 94 shift16
f180febe
TG
95.endm
96.macro add_shift8 ; ditto with carrying
97 ADD a1, i0
4466dd8b 98 shift8
f180febe
TG
99.endm
100.macro add_shift0 ; last shift is common
101 ADD a1, i0
102.endm
103
104g: ; g(i, t) -> t
d35c3d70 105 #define tmp _
65aa7cd6
TG
106 ANDI t, 0x07
107 MOV tmp, i2
108 ANDI tmp, 3
109 TST tmp
110 CPSE tmp, zero
111 SUBI t, -8
02f61e33 112 #undef tmp
4466dd8b
TG
113
114 #define tmp _
65aa7cd6
TG
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)
4466dd8b
TG
117 LDI Xlo, lo8(data)
118 ADD Xlo, tmp ;<-- the offset (formerly `t`) into data[]
65aa7cd6
TG
119 ADC Xhi, zero ; ditto skip
120 LD tmp, X
121 MOV t, tmp
4466dd8b
TG
122 #undef tmp
123
cc428230
TG
124 #define a1 x
125 #define a2 _
126 #define a0 t
65aa7cd6
TG
127 CLR a2
128 CLR a1
d0324785 129
4466dd8b
TG
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 */
65aa7cd6 144 test 0, m____1
4466dd8b 145 m____0: shift16
65aa7cd6 146 never 1
4466dd8b 147 m___00: shift16
65aa7cd6 148 test 2, m__100
4466dd8b 149 m__000: shift16
65aa7cd6 150 test 3, m_1000
4466dd8b 151 m_0000: shift16
65aa7cd6 152 always 4
4466dd8b 153 add_shift16
65aa7cd6 154 always 5
4466dd8b 155 add_shift8
65aa7cd6 156 never 6
4466dd8b 157 shift8
65aa7cd6 158 always 7
4466dd8b 159 add_shift0
65aa7cd6 160 RJMP end_mul ; calc'd 0xb0
d0324785 161
4466dd8b 162 m_1000: add_shift16
65aa7cd6 163 always 4
4466dd8b 164 add_shift16
65aa7cd6 165 never 5
4466dd8b 166 shift8
65aa7cd6 167 always 6
4466dd8b 168 add_shift8
65aa7cd6 169 never 7
4466dd8b 170 shift0
65aa7cd6 171 RJMP end_mul ; calc'd 0x58
d0324785 172
4466dd8b 173 m__100: add_shift16
65aa7cd6 174 test 3, m_1100
4466dd8b 175 m_0100: shift16
65aa7cd6 176 RJMP upper_8 ;'ll calc 0x84
d0324785 177
4466dd8b 178 m_1100: add_shift16
65aa7cd6
TG
179 upper_8: ; used twice, so deduplicated
180 never 4
4466dd8b 181 shift16
65aa7cd6 182 never 5
4466dd8b 183 shift8
65aa7cd6 184 never 6
4466dd8b 185 shift8
65aa7cd6 186 always 7
4466dd8b 187 add_shift0
65aa7cd6 188 RJMP end_mul ; calc'd 0x8c
d0324785 189
4466dd8b 190 m____1: add_shift16
65aa7cd6 191 never 1
4466dd8b 192 m___01: shift16
65aa7cd6 193 test 2, m__101
4466dd8b 194 m__001: shift16
65aa7cd6 195 always 3
4466dd8b 196 m_1001: add_shift16
65aa7cd6 197 never 4
4466dd8b 198 shift16
65aa7cd6 199 always 5
4466dd8b 200 add_shift8
65aa7cd6 201 always 6
4466dd8b 202 add_shift8
65aa7cd6 203 never 7
4466dd8b 204 shift0
65aa7cd6 205 RJMP end_mul ; calc'd 0x69
d0324785 206
4466dd8b 207 m__101: add_shift16
65aa7cd6 208 test 3, m_1101
4466dd8b 209 m_0101: shift16
65aa7cd6 210 always 4
4466dd8b 211 add_shift16
65aa7cd6 212 always 5
4466dd8b 213 add_shift8
65aa7cd6 214 always 6
4466dd8b 215 add_shift8
65aa7cd6 216 never 7
4466dd8b 217 shift0
65aa7cd6 218 RJMP end_mul ; calc'd 0x75
d0324785 219
4466dd8b 220 m_1101: add_shift16
65aa7cd6 221 always 4
4466dd8b 222 add_shift16
65aa7cd6 223 never 5
4466dd8b 224 shift8
65aa7cd6 225 never 6
4466dd8b 226 shift8
65aa7cd6 227 always 7
4466dd8b 228 add_shift0
65aa7cd6 229 ; calc'd 0x9d
d0324785 230
4466dd8b 231 end_mul:
65aa7cd6 232 LSR a1 ;final shift is a common operation for all
4466dd8b 233
65aa7cd6 234 MOV t, a1 ;;TODO: use a1 in main() directly
d0324785
TG
235 #undef a0
236 #undef a1
237 #undef a2
65aa7cd6 238 RET ; TODO: replace CALL/RET with IJMP?
61fab018 239
f180febe 240main:
65aa7cd6
TG
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
f180febe 247 RJMP sample
65aa7cd6
TG
248sample: ;;TODO: this will probably become the timer0 overflow interrupt handler
249 MOV n, i2
250 LSL n
251 LSL n
f6ef1520 252 #define tmp _
65aa7cd6
TG
253 MOV tmp, i1
254 SWAP tmp
255 ANDI tmp, 0x0f
256 LSR tmp
257 LSR tmp
258 OR n, tmp
f6ef1520 259 #undef tmp
65aa7cd6
TG
260 MOV s, i3
261 LSR s
262 ROR s
263 ANDI s, 0x80
f6ef1520 264 #define tmp _
65aa7cd6
TG
265 MOV tmp, i2
266 LSR tmp
267 OR s, tmp
f6ef1520 268 #undef tmp
3b86ca43 269
65aa7cd6
TG
270 ; voice 1:
271 MOV t, n
272 RCALL g
273 SWAP t
274 ANDI t, 1
275 MOV acc, t
3b86ca43 276
65aa7cd6 277 ; voice 2:
f6ef1520 278 #define tmp _
65aa7cd6
TG
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
f6ef1520 288 #undef tmp
65aa7cd6
TG
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
3b86ca43 296
65aa7cd6
TG
297 ; voice 3:
298 MOV Ml, i2
299 SWAP Ml
300 ANDI Ml, 0xf0
301 LSL Ml
f6ef1520 302 #define tmp _
65aa7cd6
TG
303 MOV tmp, i1
304 LSR tmp
305 LSR tmp
306 LSR tmp
307 OR Ml, tmp
f6ef1520 308 #undef tmp
65aa7cd6
TG
309 MOV Mh, i3
310 SWAP Mh
311 ANDI Mh, 0xf0
312 LSL Mh
f6ef1520 313 #define tmp _
65aa7cd6
TG
314 MOV tmp, i2
315 LSR tmp
316 LSR tmp
317 LSR tmp
318 OR Mh, tmp
f6ef1520 319 #undef tmp
65aa7cd6
TG
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
f6ef1520 328 #define tmp _
65aa7cd6
TG
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
f6ef1520 342 #undef tmp
65aa7cd6 343 ADD acc, t
f6ef1520 344
65aa7cd6
TG
345 ; voice 4:
346 MOV Ml, i2
347 SWAP Ml
348 ANDI Ml, 0xf0
349 LSL Ml
350 LSL Ml
f6ef1520 351 #define tmp _
65aa7cd6
TG
352 MOV tmp, i1
353 LSR tmp
354 LSR tmp
355 OR Ml, tmp
f6ef1520 356 #undef tmp
65aa7cd6
TG
357 MOV Mh, i3
358 SWAP Mh
359 ANDI Mh, 0xf0
360 LSL Mh
361 LSL Mh
f6ef1520 362 #define tmp _
65aa7cd6
TG
363 MOV tmp, i2
364 LSR tmp
365 LSR tmp
366 OR Mh, tmp
f6ef1520 367 #undef tmp
65aa7cd6
TG
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
f6ef1520 376 #define tmp _
65aa7cd6
TG
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
f6ef1520 390 #undef tmp
65aa7cd6 391 ADD acc, t
3b86ca43 392
f6ef1520
TG
393 SWAP acc
394 OUT OCR0AL, acc
395 SUBI i0, -1
396 SBCI i1, -1
397 SBCI i2, -1
398 SBCI i3, -1
bfce2f8c 399
65aa7cd6 400 rjmp sample ;;TODO: -> RETI
Imprint / Impressum