blob: d26409cd90666c45f05c2296567b27161bec7327 [file] [log] [blame]
Jens Arnold40919d72008-03-25 23:21:36 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Jens Arnold
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Jens Arnold40919d72008-03-25 23:21:36 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#define CLOCK_MASK 0x20000000
23#define DATA_MASK 0x04000000
24#define GPIO_OUT_ADDR 0x80000004
25
26#define CS_MASK 0x00010000
27#define RS_MASK 0x00001000
28#define GPIO1_OUT_ADDR 0x800000b4
29
30 .extern cpu_frequency /* Global variable from system.c */
31
32 .section .icode,"ax",@progbits
33
34 /* Output 8 bits to the LCD. Instruction order is devised to maximize the
35 * delay between changing the data line and the CLK L->H transition, which
36 * makes the LCD controller sample DATA.
Jens Arnold06ec18d2008-03-26 23:45:55 +000037 * Requires CLK = 1 on entry.
Jens Arnold40919d72008-03-25 23:21:36 +000038 *
39 * Custom calling convention:
40 * %a0 - GPIO_OUT_ADDR
41 * %d3 - data byte
42 * %d6 - DATA_MASK
43 * %d7 - CLOCK_MASK
44 * Clobbers:
45 * %d0..%d3
46 */
47.write_byte:
48 move.w %sr, %d2
49 move.w #0x2700, %sr
50
51 move.l (%a0), %d0 /* Get current state of data port */
52 move.l %d0, %d1
53 and.l %d6, %d1 /* Check current state of data line */
54 beq.s 1f /* and set it as previous-state bit */
55 bset #8, %d3
561:
57 move.l %d3, %d1 /* Compute the 'bit derivative', i.e. a value */
58 lsr.l #1, %d1 /* with 1's where the data changes from the */
59 eor.l %d1, %d3 /* previous state, and 0's where it doesn't */
60 swap %d3 /* Shift data to upper byte */
61 lsl.l #8, %d3
62
Jens Arnold4a6190d2008-05-24 08:53:12 +000063 move.l %d0, %d1 /* precalculate opposite state of clock line */
64 eor.l %d7, %d1
Jens Arnold40919d72008-03-25 23:21:36 +000065
Jens Arnold4a6190d2008-05-24 08:53:12 +000066 lsl.l #1, %d3 /* Shift out MSB */
Jens Arnold40919d72008-03-25 23:21:36 +000067 bcc.s 1f
68 eor.l %d6, %d0 /* 1: Flip data bit */
Jens Arnold4a6190d2008-05-24 08:53:12 +000069 eor.l %d6, %d1
Jens Arnold40919d72008-03-25 23:21:36 +0000701:
Jens Arnold4a6190d2008-05-24 08:53:12 +000071 move.l %d1, (%a0) /* Output new state and set CLK = 0*/
Jens Arnold40919d72008-03-25 23:21:36 +000072 bra.w .wr_bit7
73
74
75 /* Output 16 bits to the LCD. Instruction order is devised to maximize the
76 * delay between changing the data line and the CLK L->H transition, which
77 * makes the LCD controller sample DATA.
Jens Arnold06ec18d2008-03-26 23:45:55 +000078 * Requires CLK = 1 on entry.
Jens Arnold40919d72008-03-25 23:21:36 +000079 *
80 * Custom calling convention:
81 * %a0 - GPIO_OUT_ADDR
82 * %d3 - data word
83 * %d6 - DATA_MASK
84 * %d7 - CLOCK_MASK
85 * Clobbers:
86 * %d0..%d3
87 */
88.write_word:
89 move.w %sr, %d2
90 move.w #0x2700, %sr
91
92 move.l (%a0), %d0 /* Get current state of data port */
93 move.l %d0, %d1
94 and.l %d6, %d1 /* Check current state of data line */
95 beq.s 1f /* and set it as previous-state bit */
96 bset #16, %d3
971:
98 move.l %d3, %d1 /* Compute the 'bit derivative', i.e. a value */
99 lsr.l #1, %d1 /* with 1's where the data changes from the */
100 eor.l %d1, %d3 /* previous state, and 0's where it doesn't */
101 swap %d3 /* Shift data to upper word */
102
Jens Arnold4a6190d2008-05-24 08:53:12 +0000103 move.l %d0, %d1 /* precalculate opposite state of clock line */
104 eor.l %d7, %d1
Jens Arnold40919d72008-03-25 23:21:36 +0000105
Jens Arnold4a6190d2008-05-24 08:53:12 +0000106 lsl.l #1, %d3 /* Shift out MSB */
Jens Arnold40919d72008-03-25 23:21:36 +0000107 bcc.s 1f
108 eor.l %d6, %d0 /* 1: Flip data bit */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000109 eor.l %d6, %d1
Jens Arnold40919d72008-03-25 23:21:36 +00001101:
Jens Arnold4a6190d2008-05-24 08:53:12 +0000111 move.l %d1, (%a0) /* Output new state and set CLK = 0*/
Jens Arnold40919d72008-03-25 23:21:36 +0000112
113.macro bit_out
Jens Arnold4a6190d2008-05-24 08:53:12 +0000114 move.l %d0, (%a0) /* Set CLK = 1 */
115 lsl.l #1, %d3
Jens Arnold40919d72008-03-25 23:21:36 +0000116 bcc.s 1f
117 eor.l %d6, %d0
Jens Arnold4a6190d2008-05-24 08:53:12 +0000118 eor.l %d6, %d1
Jens Arnold40919d72008-03-25 23:21:36 +00001191:
Jens Arnold4a6190d2008-05-24 08:53:12 +0000120 move.l %d1, (%a0)
Jens Arnold40919d72008-03-25 23:21:36 +0000121.endm
Jens Arnold40919d72008-03-25 23:21:36 +0000122
Jens Arnold4a6190d2008-05-24 08:53:12 +0000123 nop
124 nop
125 bit_out
126 nop
127 nop
128 bit_out
129 nop
130 nop
131 bit_out
132 nop
133 nop
134 bit_out
135 nop
136 nop
137 bit_out
138 nop
139 nop
140 bit_out
141 nop
142 nop
143 bit_out
144 nop
145 nop
146 bit_out
147
148 nop
Jens Arnold40919d72008-03-25 23:21:36 +0000149.wr_bit7:
Jens Arnold40919d72008-03-25 23:21:36 +0000150 nop
151 bit_out
152 nop
Jens Arnold40919d72008-03-25 23:21:36 +0000153 nop
154 bit_out
155 nop
Jens Arnold40919d72008-03-25 23:21:36 +0000156 nop
157 bit_out
158 nop
Jens Arnold4a6190d2008-05-24 08:53:12 +0000159 nop
Jens Arnold40919d72008-03-25 23:21:36 +0000160 bit_out
161 nop
Jens Arnold4a6190d2008-05-24 08:53:12 +0000162 nop
163 bit_out
164 nop
165 nop
166 bit_out
167 nop
168 nop
169 bit_out
170 nop
171 nop
Jens Arnold40919d72008-03-25 23:21:36 +0000172
Jens Arnold4a6190d2008-05-24 08:53:12 +0000173 move.l %d0, (%a0) /* Set CLK = 1 */
Jens Arnold40919d72008-03-25 23:21:36 +0000174 move.w %d2, %sr
175 rts
176
177
178 /* Output 16 bits to the LCD as fast as possible. Use only at < 60MHz.
179 *
180 * Custom calling convention:
181 * %a0 - GPIO_OUT_ADDR
182 * %d3 - data word
183 * %d6 - DATA_MASK
184 * %d7 - CLOCK_MASK
185 * Clobbers:
186 * %d0..%d3
187 */
188.write_word_fast:
189 move.w %sr, %d2 /* Get current interrupt level */
190 move.w #0x2700, %sr /* Disable interrupts */
191
192 move.l (%a0), %d0 /* Get current state of data port */
193 move.l %d0, %d1
194 and.l %d6, %d1 /* Check current state of data line */
195 beq.s 1f /* and set it as previous-state bit */
196 bset #16, %d3
1971:
198 move.l %d3, %d1 /* Compute the 'bit derivative', i.e. a value */
199 lsr.l #1, %d1 /* with 1's where the data changes from the */
200 eor.l %d1, %d3 /* previous state, and 0's where it doesn't */
201 swap %d3 /* Shift data to upper byte */
202
203 move.l %d0, %d1 /* precalculate opposite state of clock line */
204 eor.l %d7, %d1
205
206.macro bit_out_fast
207 lsl.l #1,%d3 /* Shift out MSB */
208 bcc.s 1f
209 eor.l %d6, %d0 /* 1: Flip data bit */
210 eor.l %d6, %d1 /* for both clock states */
2111:
212 move.l %d1, (%a0) /* Output new state and set CLK = 0*/
213 move.l %d0, (%a0) /* set CLK = 1 */
214.endm
Jens Arnold4a6190d2008-05-24 08:53:12 +0000215
Jens Arnold40919d72008-03-25 23:21:36 +0000216 bit_out_fast
217 bit_out_fast
218 bit_out_fast
219 bit_out_fast
220 bit_out_fast
221 bit_out_fast
222 bit_out_fast
223 bit_out_fast
224 bit_out_fast
225 bit_out_fast
226 bit_out_fast
227 bit_out_fast
228 bit_out_fast
229 bit_out_fast
230 bit_out_fast
231 bit_out_fast
232
233 move.w %d2, %sr /* Restore interrupt level */
234 rts
235
236
237 .global lcd_write_command
238 .type lcd_write_command, @function
239
240lcd_write_command:
241 lea.l (-4*4, %sp), %sp
242 movem.l %d2-%d3/%d6-%d7, (%sp)
243
244 move.l (4*4+4, %sp), %d3 /* cmd */
245
246 lea.l GPIO_OUT_ADDR, %a0
247 lea.l GPIO1_OUT_ADDR, %a1
248 move.l #DATA_MASK, %d6
249 move.l #CLOCK_MASK, %d7
250
251 move.l #~(RS_MASK+CS_MASK), %d0
252 and.l %d0, (%a1)
253
254 bsr.w .write_byte
255
256 move.l #CS_MASK, %d0
257 or.l %d0, (%a1)
258
259 movem.l (%sp), %d2-%d3/%d6-%d7
260 lea.l (4*4, %sp), %sp
261 rts
262
263
264 .global lcd_write_command_e
265 .type lcd_write_command_e, @function
266
267lcd_write_command_e:
268 lea.l (-4*4, %sp), %sp
269 movem.l %d2-%d3/%d6-%d7, (%sp)
270
271 movem.l (4*4+4, %sp), %d2-%d3 /* cmd, data */
272
273 lea.l GPIO_OUT_ADDR, %a0
274 lea.l GPIO1_OUT_ADDR, %a1
275 move.l #DATA_MASK, %d6
276 move.l #CLOCK_MASK, %d7
277
278 move.l #~(RS_MASK+CS_MASK), %d0
279 and.l %d0, (%a1)
280
281 lsl.l #8, %d2
282 or.l %d2, %d3
283 bsr.w .write_word
284
285 move.l #CS_MASK, %d0
286 or.l %d0, (%a1)
287
288 movem.l (%sp), %d2-%d3/%d6-%d7
289 lea.l (4*4, %sp), %sp
290 rts
291
292
293 .global lcd_write_data
294 .type lcd_write_data, @function
295
296lcd_write_data:
297 lea.l (-7*4, %sp), %sp
298 movem.l %d2-%d4/%d6-%d7/%a2-%a3, (%sp)
299
300 move.l (7*4+4, %sp), %a2 /* p_words */
301 move.l (7*4+8, %sp), %d4 /* count */
302
303 lea.l GPIO_OUT_ADDR, %a0
304 lea.l GPIO1_OUT_ADDR, %a1
305 move.l #DATA_MASK, %d6
306 move.l #CLOCK_MASK, %d7
307
308 lea.l .write_word, %a3
309 move.l cpu_frequency, %d0
310 cmp.l #60000000, %d0
311 bhi.b 1f
312 lea.l .write_word_fast, %a3
3131:
314
315 move.l #RS_MASK, %d0
316 or.l %d0, (%a1)
317 move.l #~CS_MASK, %d0
318 and.l %d0, (%a1)
319
320.wd_loop:
321 clr.l %d3
322 move.w (%a2)+, %d3
323 jsr (%a3)
324 subq.l #1, %d4
325 bne.s .wd_loop
326
327 move.l #CS_MASK, %d0
328 or.l %d0, (%a1)
329
330 movem.l (%sp), %d2-%d4/%d6-%d7/%a2-%a3
331 lea.l (7*4, %sp), %sp
332 rts
Jens Arnold06ec18d2008-03-26 23:45:55 +0000333
Jens Arnold40919d72008-03-25 23:21:36 +0000334
335/*** The following functions are only needed for main LCDs ***/
336
337
338 .global lcd_mono_data
339 .type lcd_mono_data, @function
340
341lcd_mono_data:
342 lea.l (-7*4, %sp), %sp
343 movem.l %d2-%d4/%d6-%d7/%a2-%a3, (%sp)
344
345 move.l (7*4+4, %sp), %a2 /* p_bytes */
346 move.l (7*4+8, %sp), %d4 /* count */
347
348 lea.l GPIO_OUT_ADDR, %a0
349 lea.l GPIO1_OUT_ADDR, %a1
350 move.l #DATA_MASK, %d6
351 move.l #CLOCK_MASK, %d7
352
353 lea.l .write_word, %a3
354 move.l cpu_frequency, %d0
355 cmp.l #60000000, %d0
356 bhi.b 1f
357 lea.l .write_word_fast, %a3
3581:
359
360 move.l #RS_MASK, %d0
361 or.l %d0, (%a1)
362 move.l #~CS_MASK, %d0
363 and.l %d0, (%a1)
364
365.md_loop:
366 clr.l %d3
367 move.b (%a2)+, %d3
368 move.l %d3, %d2
369 lsl.l #8, %d2
370 or.l %d2, %d3
371 jsr (%a3)
372 subq.l #1, %d4
373 bne.s .md_loop
374
375 move.l #CS_MASK, %d0
376 or.l %d0, (%a1)
377
378 movem.l (%sp), %d2-%d4/%d6-%d7/%a2-%a3
379 lea.l (7*4, %sp), %sp
380 rts
381
382
383 .global lcd_grey_data
384 .type lcd_grey_data,@function
385
386lcd_grey_data:
387 lea.l (-9*4, %sp), %sp
388 movem.l %d2-%d7/%a2-%a4, (%sp)
389
390 movem.l (9*4+4, %sp), %a2-%a4 /* values, phases, length */
391 add.l %a4, %a4
392 lea.l (%a3, %a4.l*4), %a4 /* end address */
393
394 lea.l GPIO_OUT_ADDR, %a0
395 lea.l GPIO1_OUT_ADDR, %a1
396 move.l #DATA_MASK, %d6
397 move.l #CLOCK_MASK, %d7
398
399 move.l #RS_MASK, %d0
400 or.l %d0, (%a1)
401 move.l #~CS_MASK, %d0
402 and.l %d0, (%a1)
403
404 clr.l %d5
405 move.l (%a3), %d4 /* fetch 4 pixel phases */
406 bclr.l #31, %d4 /* Z = !(p0 & 0x80); p0 &= ~0x80; */
407 seq.b %d5 /* %d5 = ........................00000000 */
408 lsl.l #1, %d5 /* %d5 = .......................00000000. */
409 bclr.l #23, %d4 /* Z = !(p1 & 0x80); p1 &= ~0x80; */
410 seq.b %d5 /* %d5 = .......................011111111 */
411 lsl.l #1, %d5 /* %d5 = ......................011111111. */
412 bclr.l #15, %d4 /* Z = !(p2 & 0x80); p2 &= ~0x80; */
413 seq.b %d5 /* %d5 = ......................0122222222 */
414 lsl.l #1, %d5 /* %d5 = .....................0122222222. */
415 bclr.l #7, %d4 /* Z = !(p3 & 0x80); p3 &= ~0x80; */
416 seq.b %d5 /* %d5 = .....................01233333333 */
417 lsl.l #1, %d5 /* %d5 = ....................01233333333. */
418 add.l (%a2)+, %d4 /* add 4 pixel values to the phases */
419 move.l %d4, (%a3)+ /* store new phases, advance pointer */
420
421 move.l (%a3), %d4 /* fetch 4 pixel phases */
422 bclr.l #31, %d4 /* Z = !(p0 & 0x80); p0 &= ~0x80; */
423 seq.b %d5 /* %d5 = ....................012344444444 */
424 lsl.l #1, %d5 /* %d5 = ...................012344444444. */
425 bclr.l #23, %d4 /* Z = !(p1 & 0x80); p1 &= ~0x80; */
426 seq.b %d5 /* %d5 = ...................0123455555555 */
427 lsl.l #1, %d5 /* %d5 = ..................0123455555555. */
428 bclr.l #15, %d4 /* Z = !(p2 & 0x80); p2 &= ~0x80; */
429 seq.b %d5 /* %d5 = ..................01234566666666 */
430 lsl.l #1, %d5 /* %d5 = .................01234566666666. */
431 bclr.l #7, %d4 /* Z = !(p3 & 0x80); p3 &= ~0x80; */
432 seq.b %d5 /* %d5 = .................012345677777777 */
433 lsr.l #7, %d5 /* %d5 = ........................01234567 */
434 add.l (%a2)+, %d4 /* add 4 pixel values to the phases */
435 move.l %d4, (%a3)+ /* store new phases, advance pointer */
436
437 move.l %d5, %d3
438 lsl.l #8, %d3
439 or.l %d5, %d3
440
441 cmp.l %a3, %a4
442 bls.w .gd_last
443
444.gd_loop:
445 move.w %sr, %d2
446 move.w #0x2700, %sr
447
448 move.l (%a0), %d0 /* Get current state of data port */
449 move.l %d0, %d1
450 and.l %d6, %d1 /* Check current state of data line */
451 beq.s 1f /* and set it as previous-state bit */
452 bset #16, %d3
4531:
454 move.l %d3, %d1 /* Compute the 'bit derivative', i.e. a value */
455 lsr.l #1, %d1 /* with 1's where the data changes from the */
456 eor.l %d1, %d3 /* previous state, and 0's where it doesn't */
457 swap %d3 /* Shift data to upper word */
458
Jens Arnold4a6190d2008-05-24 08:53:12 +0000459 move.l %d0, %d1 /* precalculate opposite state of clock line */
460 eor.l %d7, %d1
Jens Arnold40919d72008-03-25 23:21:36 +0000461
Jens Arnold4a6190d2008-05-24 08:53:12 +0000462 lsl.l #1, %d3 /* Shift out MSB */
Jens Arnold40919d72008-03-25 23:21:36 +0000463 bcc.s 1f
464 eor.l %d6, %d0 /* 1: Flip data bit */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000465 eor.l %d6, %d1
Jens Arnold40919d72008-03-25 23:21:36 +00004661:
Jens Arnold4a6190d2008-05-24 08:53:12 +0000467 move.l %d1, (%a0) /* Output new state and set CLK = 0*/
Jens Arnold40919d72008-03-25 23:21:36 +0000468
469 move.l (%a3), %d4 /* fetch 4 pixel phases */
470 bit_out
471 bclr.l #31, %d4 /* Z = !(p0 & 0x80); p0 &= ~0x80; */
472 seq.b %d5 /* %d5 = ........................00000000 */
473 lsl.l #1, %d5 /* %d5 = .......................00000000. */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000474 trapf
475 trapf
Jens Arnold40919d72008-03-25 23:21:36 +0000476 bit_out
477 bclr.l #23, %d4 /* Z = !(p1 & 0x80); p1 &= ~0x80; */
478 seq.b %d5 /* %d5 = .......................011111111 */
479 lsl.l #1, %d5 /* %d5 = ......................011111111. */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000480 trapf
481 trapf
Jens Arnold40919d72008-03-25 23:21:36 +0000482 bit_out
483 bclr.l #15, %d4 /* Z = !(p2 & 0x80); p2 &= ~0x80; */
484 seq.b %d5 /* %d5 = ......................0122222222 */
485 lsl.l #1, %d5 /* %d5 = .....................0122222222. */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000486 trapf
487 trapf
Jens Arnold40919d72008-03-25 23:21:36 +0000488 bit_out
489 bclr.l #7, %d4 /* Z = !(p3 & 0x80); p3 &= ~0x80; */
490 seq.b %d5 /* %d5 = .....................01233333333 */
491 lsl.l #1, %d5 /* %d5 = ....................01233333333. */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000492 trapf
493 trapf
Jens Arnold40919d72008-03-25 23:21:36 +0000494 bit_out
495 add.l (%a2)+, %d4 /* add 4 pixel values to the phases */
496 bit_out
497 move.l %d4, (%a3)+ /* store new phases, advance pointer */
498
499 bit_out
500 move.l (%a3), %d4 /* fetch 4 pixel phases */
501 bit_out
502 bclr.l #31, %d4 /* Z = !(p0 & 0x80); p0 &= ~0x80; */
503 seq.b %d5 /* %d5 = ....................012344444444 */
504 lsl.l #1, %d5 /* %d5 = ...................012344444444. */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000505 trapf
506 trapf
Jens Arnold40919d72008-03-25 23:21:36 +0000507 bit_out
508 bclr.l #23, %d4 /* Z = !(p1 & 0x80); p1 &= ~0x80; */
509 seq.b %d5 /* %d5 = ...................0123455555555 */
510 lsl.l #1, %d5 /* %d5 = ..................0123455555555. */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000511 trapf
512 trapf
Jens Arnold40919d72008-03-25 23:21:36 +0000513 bit_out
514 bclr.l #15, %d4 /* Z = !(p2 & 0x80); p2 &= ~0x80; */
515 seq.b %d5 /* %d5 = ..................01234566666666 */
516 lsl.l #1, %d5 /* %d5 = .................01234566666666. */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000517 trapf
518 trapf
Jens Arnold40919d72008-03-25 23:21:36 +0000519 bit_out
520 bclr.l #7, %d4 /* Z = !(p3 & 0x80); p3 &= ~0x80; */
521 seq.b %d5 /* %d5 = .................012345677777777 */
522 lsr.l #7, %d5 /* %d5 = ........................01234567 */
Jens Arnold4a6190d2008-05-24 08:53:12 +0000523 trapf
524 trapf
Jens Arnold40919d72008-03-25 23:21:36 +0000525 bit_out
526 add.l (%a2)+, %d4 /* add 4 pixel values to the phases */
527 bit_out
528 move.l %d4, (%a3)+ /* store new phases, advance pointer */
529
530 bit_out
531 nop
Jens Arnold4a6190d2008-05-24 08:53:12 +0000532 nop
Jens Arnold40919d72008-03-25 23:21:36 +0000533 bit_out
534 move.l %d5, %d3
535 lsl.l #8, %d3
536 or.l %d5, %d3
Jens Arnold40919d72008-03-25 23:21:36 +0000537 nop
Jens Arnold4a6190d2008-05-24 08:53:12 +0000538
539 move.l %d0, (%a0) /* Set CLK = 1 */
Jens Arnold40919d72008-03-25 23:21:36 +0000540 move.w %d2, %sr
541
542 cmp.l %a3, %a4
543 bhi.w .gd_loop
544
545.gd_last:
546 bsr.w .write_word
547
548 move.l #CS_MASK, %d0
549 or.l %d0, (%a1)
550
551 movem.l (%sp), %d2-%d7/%a2-%a4
552 lea.l (9*4, %sp), %sp
553 rts