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