summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2005-07-06 18:46:04 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2005-07-06 18:46:04 +0000
commit3c7ed6b8cd505f696c9c2b6d90723094f334b348 (patch)
tree30da596d32865c2d042ece5735d16baeade7d17d /c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S
parente9b4f29a409d9dc192a85dbbe693aeb1fa87e43b (diff)
downloadrtems-3c7ed6b8cd505f696c9c2b6d90723094f334b348.tar.bz2
2005-07-06 Markku Puro <markku.puro@kopteri.net>
* .cvsignore, ChangeLog, Makefile.am, README, bsp_specs, configure.ac, clock/clockdrv.c, console/conio.c, console/console.c, console/defaultfont.c, include/arm_mode_bits.h, include/asm_macros.h, include/bsp.h, include/bspopts.h.in, include/conio.h, include/gba.h, include/gba_registers.h, include/tm27.h, irq/bsp_irq_asm.S, irq/bsp_irq_init.c, irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c, start/logo.S, start/start.S, startup/bspstart.c, startup/cpu.c, startup/cpu_asm.S, startup/exit.c, startup/linkcmds, timer/timer.c: New files.
Diffstat (limited to 'c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S')
-rw-r--r--c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S179
1 files changed, 179 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S b/c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S
new file mode 100644
index 0000000000..3697b5e018
--- /dev/null
+++ b/c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S
@@ -0,0 +1,179 @@
+/**
+ * @file bsp_irq_asm.S
+ *
+ * Intererrupt handler for GameBoy Advance.
+ */
+/*
+ * RTEMS GBA BSP
+ *
+ * Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#define __asm__
+#include <asm_macros.h>
+#include <gba_registers.h>
+#include <arm_mode_bits.h>
+/* @cond INCLUDE_ASM */
+
+/**
+ * Execute interrupt handler
+ * function void ExecuteITHandler(void)
+ *
+ * Look at interrupt status register to determine source.
+ * From source, determine offset into expanded vector table
+ * and load handler address into r0.
+ * irq_vector_table is defined in linkcmds
+ *
+ */
+ .align
+/* .section .iwram */
+
+PUBLIC_ARM_FUNCTION(ExecuteITHandler)
+ ldr r1, =GBA_REG_IE_ADDR
+ ldrh r1, [r1]
+ ldr r2, =GBA_REG_IF_ADDR
+ ldrh r2, [r2]
+ and r3, r1, r2 /* only look at interrupts which are enabled */
+
+check_lcdv:
+ tst r3, #0x0001
+ beq check_lcdh
+ ldr r0, =(irq_vector_table + (4 * 0)) /* load the vector number */
+ ldr r3,=0x0001
+ b get_handler
+
+check_lcdh:
+ tst r3, #0x0002
+ beq check_lcdvc
+ ldr r0, =(irq_vector_table + (4 * 1)) /* load the vector number */
+ ldr r3,=0x0002
+ b get_handler
+
+check_lcdvc:
+ tst r3, #0x0004
+ beq check_t0
+ ldr r0, =(irq_vector_table + (4 * 2)) /* load the vector number */
+ ldr r3,=0x0004
+ b get_handler
+
+check_t0:
+ tst r3, #0x0008
+ beq check_t1
+ ldr r0, =(irq_vector_table + (4 * 3)) /* load the vector number */
+ ldr r3,=0x0008
+ b get_handler
+
+check_t1:
+ tst r3, #0x0010
+ beq check_t2
+ ldr r0, =(irq_vector_table + (4 * 4)) /* load the vector number */
+ ldr r3,=0x0010
+ b get_handler
+
+check_t2:
+ tst r3, #0x0020
+ beq check_t3
+ ldr r0, =(irq_vector_table + (4 * 5)) /* load the vector number */
+ ldr r3,=0x0020
+ b get_handler
+
+check_t3:
+ tst r3, #0x0040
+ beq check_ser
+ ldr r0, =(irq_vector_table + (4 * 6)) /* load the vector number */
+ ldr r3,=0x0040
+ b get_handler
+
+check_ser:
+ tst r3, #0x0080
+ beq check_dma0
+ ldr r0, =(irq_vector_table + (4 * 7)) /* load the vector number */
+ ldr r3,=0x0080
+ b get_handler
+
+check_dma0:
+ tst r3, #0x0100
+ beq check_dma1
+ ldr r0, =(irq_vector_table + (4 * 8)) /* load the vector number */
+ ldr r3,=0x0100
+ b get_handler
+
+check_dma1:
+ tst r3, #0x0200
+ beq check_dma2
+ ldr r0, =(irq_vector_table + (4 * 9)) /* load the vector number */
+ ldr r3,=0x0200
+ b get_handler
+
+check_dma2:
+ tst r3, #0x0400
+ beq check_dma3
+ ldr r0, =(irq_vector_table + (4 * 10)) /* load the vector number */
+ ldr r3,=0x0400
+ b get_handler
+
+check_dma3:
+ tst r3, #0x0800
+ beq check_keypad
+ ldr r0, =(irq_vector_table + (4 * 11)) /* load the vector number */
+ ldr r3,=0x0800
+ b get_handler
+
+check_keypad:
+ tst r3, #0x1000
+ beq check_gamepak
+ ldr r0, =(irq_vector_table + (4 * 12)) /* load the vector number */
+ ldr r3,=0x1000
+ b get_handler
+
+check_gamepak:
+ tst r3, #0x2000
+ beq IRQ_NoInterrupt
+ ldr r0, =(irq_vector_table + (4 * 13)) /* load the vector number */
+ ldr r3,=0x2000
+ b get_handler
+
+unknown_irq:
+ ldr r0, =(default_int_handler) /* Unknown Interrupt? */
+ ldr r3,=0x0000
+
+get_handler:
+ ldr r0, [r0] /* extract the IT handler */
+
+ ldr r2, =GBA_REG_IF_ADDR /* Clear IF */
+ strh r3, [r2]
+
+ /*
+ * re-enable interrupts at processor level
+ */
+ mrs r1, cpsr
+ bic r1, r1, #Int_Bits
+ msr cpsr, r1
+
+ stmdb sp!,{lr}
+ ldr lr, =IRQ_return /* prepare the return from handler */
+ mov pc, r0 /* EXECUTE INT HANDLER */
+
+IRQ_return:
+ ldmia sp!,{lr}
+
+ /*
+ * disable interrupts_again
+ */
+ mrs r0, cpsr
+ orr r0, r0, #Int_Bits
+ msr cpsr, r0
+
+IRQ_NoInterrupt:
+ /* return to the "main" interrupt handler */
+ mov pc, lr
+
+LABEL_END(ExecuteITHandler)
+/* @endcond */
+