summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2006-03-05 21:16:57 +0000
committerThom Johansen <thomj@rockbox.org>2006-03-05 21:16:57 +0000
commit149df9794ee3513cd815c095ad3cb65e4346d6a4 (patch)
treecd1164c07c14e1dc8008224205339a51061a07e2
parentd11f15fcc3b20a1c7a7226aeb8e100c5b6ed6234 (diff)
downloadrockbox-149df9794ee3513cd815c095ad3cb65e4346d6a4.zip
rockbox-149df9794ee3513cd815c095ad3cb65e4346d6a4.tar.gz
rockbox-149df9794ee3513cd815c095ad3cb65e4346d6a4.tar.bz2
rockbox-149df9794ee3513cd815c095ad3cb65e4346d6a4.tar.xz
Make better use of banked registers in FIQ mode to shrink the iPod FIQ
handler a bit. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8920 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/crt0.S6
-rw-r--r--firmware/pcm_playback.c72
2 files changed, 41 insertions, 37 deletions
diff --git a/firmware/crt0.S b/firmware/crt0.S
index 061ffeb..e7210e6 100644
--- a/firmware/crt0.S
+++ b/firmware/crt0.S
@@ -285,6 +285,12 @@ boot_table:
/* Set up stack for FIQ mode */
msr cpsr_c, #0xd1
ldr sp, =fiq_stack
+#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002
+ /* We'll load the banked FIQ mode registers with useful values here.
+ These values will be used in the FIQ handler in pcm_playback.c */
+ ldr r12, =0x70002800 /* IISCONFIG */
+ ldr r11, =p
+#endif
/* Let abort mode use IRQ stack */
msr cpsr_c, #0xd7
ldr sp, =irq_stack
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index 6d60c40..75b3de4 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -330,6 +330,8 @@ static bool pcm_playing;
static bool pcm_paused;
static int pcm_freq = 0x6; /* 44.1 is default */
+/* NOTE: The order of these two variables is important if you use the iPod
+ assembler optimised fiq handler, so don't change it. */
unsigned short* p IBSS_ATTR;
long p_size IBSS_ATTR;
@@ -552,36 +554,38 @@ bool pcm_is_playing(void)
void fiq(void) ICODE_ATTR __attribute__((naked));
void fiq(void)
{
+ /* r12 contains IISCONFIG address (set in crt0.S to minimise code in actual
+ * FIQ handler. r11 contains address of p (also set in crt0.S). Most other
+ * addresses we need are generated by using offsets with these two.
+ * r12 + 0x40 is IISFIFO_WR, and r12 + 0x0c is IISFIFO_CFG.
+ * r8 and r9 contains local copies of p_size and p respectively.
+ * r10 is a working register.
+ */
asm volatile (
- "ldr r12, =0x70002800 \n\t" /* r12 = IISCONFIG */
- "ldr r11, [r12] \n\t"
- "bic r11, r11, #0x2 \n\t" /* clear interrupt */
- "str r11, [r12] \n\t"
- "ldr r8, =p_size \n\t"
- "ldr r9, =p \n\t"
- "ldr r8, [r8] \n\t" /* r8 = p_size */
- "ldr r9, [r9] \n\t" /* r9 = p */
- "ldr r10, =0x70002840 \n\t" /* r10 = IISFIFO_WR */
- "ldr r11, =0x7000280c \n\t" /* r11 = IISFIFO_CFG */
+ "ldr r10, [r12] \n\t"
+ "bic r10, r10, #0x2 \n\t" /* clear interrupt */
+ "str r10, [r12] \n\t"
+ "ldr r8, [r11, #4] \n\t" /* r8 = p_size */
+ "ldr r9, [r11] \n\t" /* r9 = p */
".loop: \n\t"
"cmp r8, #0 \n\t" /* is p_size 0? */
"beq .more_data \n\t" /* if so, ask pcmbuf for more data */
".fifo_loop: \n\t"
- "ldr r12, [r11] \n\t" /* read IISFIFO_CFG to check FIFO status */
- "and r12, r12, #0x3f0000\n\t"
- "cmp r12, #0x10000 \n\t"
+ "ldr r10, [r12, #0x0c]\n\t" /* read IISFIFO_CFG to check FIFO status */
+ "and r10, r10, #0x3f0000\n\t"
+ "cmp r10, #0x10000 \n\t"
"bls .fifo_full \n\t" /* FIFO full, exit */
- "ldr r12, [r9], #4 \n\t" /* load two samples to r12 */
- "mov r12, r12, ror #16\n\t" /* put left sample at the top bits */
- "str r12, [r10] \n\t" /* write top sample, lower sample ignored */
- "mov r12, r12, lsl #16\n\t" /* shift lower sample up */
- "str r12, [r10] \n\t" /* then write it */
+ "ldr r10, [r9], #4 \n\t" /* load two samples */
+ "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */
+ "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */
+ "mov r10, r10, lsl #16\n\t" /* shift lower sample up */
+ "str r10, [r12, #0x40]\n\t" /* then write it */
"subs r8, r8, #4 \n\t" /* check if we have more samples */
"bne .fifo_loop \n\t" /* yes, continue */
".more_data: \n\t"
- "stmdb sp!, { r0-r3, lr}\n\t" /* stack scratch regs and lr */
- "ldr r0, =p \n\t" /* load parameters to callback_for_more */
- "ldr r1, =p_size \n\t"
+ "stmdb sp!, { r0-r3, r12, lr}\n\t" /* stack scratch regs and lr */
+ "mov r0, r11 \n\t" /* r0 = &p */
+ "add r1, r11, #4 \n\t" /* r1 = &p_size */
"str r9, [r0] \n\t" /* save internal copies of variables back */
"str r8, [r1] \n\t"
"ldr r2, =callback_for_more\n\t"
@@ -589,36 +593,30 @@ void fiq(void)
"cmp r2, #0 \n\t" /* check for null pointer */
"movne lr, pc \n\t" /* call callback_for_more */
"bxne r2 \n\t"
- "ldmia sp!, { r0-r3, lr}\n\t"
- "ldr r8, =p_size \n\t" /* reload p_size and p */
- "ldr r9, =p \n\t"
- "ldr r8, [r8] \n\t"
- "ldr r9, [r9] \n\t"
+ "ldmia sp!, { r0-r3, r12, lr}\n\t"
+ "ldr r8, [r11, #4] \n\t" /* reload p_size and p */
+ "ldr r9, [r11] \n\t"
"cmp r8, #0 \n\t" /* did we actually get more data? */
"bne .loop \n\t" /* yes, continue to try feeding FIFO */
".dma_stop: \n\t" /* no more data, do dma_stop() and exit */
"ldr r10, =pcm_playing\n\t"
"strb r8, [r10] \n\t" /* pcm_playing = false (r8=0, look above) */
- "ldr r10, =0x70002800 \n\t" /* r10 = IISCONFIG */
- "ldr r11, [r10] \n\t"
- "bic r11, r11, #0x20000002\n\t" /* disable playback FIFO and IRQ */
- "str r11, [r10] \n\t"
+ "ldr r10, [r12] \n\t"
+ "bic r10, r10, #0x20000002\n\t" /* disable playback FIFO and IRQ */
+ "str r10, [r12] \n\t"
"mrs r10, cpsr \n\t"
"orr r10, r10, #0x40 \n\t" /* disable FIQ */
"msr cpsr_c, r10 \n\t"
"ldr r10, =pcm_paused \n\t"
"strb r8, [r10] \n\t" /* pcm_paused = false */
".exit: \n\t"
- "ldr r10, =p_size \n\t" /* save back p_size and p, then exit */
- "ldr r11, =p \n\t"
- "str r8, [r10] \n\t"
+ "str r8, [r11, #4] \n\t"
"str r9, [r11] \n\t"
"subs pc, lr, #4 \n\t" /* FIQ specific return sequence */
".fifo_full: \n\t" /* enable IRQ and exit */
- "ldr r12, =0x70002800 \n\t" /* r12 = IISCONFIG */
- "ldr r11, [r12] \n\t"
- "orr r11, r11, #0x2 \n\t" /* set interrupt */
- "str r11, [r12] \n\t"
+ "ldr r10, [r12] \n\t"
+ "orr r10, r10, #0x2 \n\t" /* set interrupt */
+ "str r10, [r12] \n\t"
"b .exit \n\t"
);
}