gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Multitasking on GBA

#37822 - DecayCell - Thu Mar 17, 2005 11:11 am

I'm trying to build a multitasking system on the GBA, but I can't find resources on the net about it -- especially about the assembly context switching part.
I've written a test program, but it fails to work and I have absolutely no way to debug it, since GDB drives me through hell on my GNU/Linux box. I'm attaching the relevant assembly code:

Code:
   .section   ".text"
   .align
   .arm

   .global _preempt
@-------------------------------------------------------------------------------
_preempt:
@-------------------------------------------------------------------------------
   @ Disable interrupts
   mov      r0,   #0x4000000
   add      r0,r0,#208
   mov      r1, #0
   strb   r1, [r0]

   @ Copy BIOS-backuped registers from stack to memory
   ldr      r0, =_current_regs
   sub      r1, sp, #24
   ldr      r2, [r1]
   str      r2, [r0]      @ r0
   add      r0, r0, #4
   add      r1, r1, #4
   ldr      r2, [r1]
   str      r2, [r0]      @ r1
   add      r0, r0, #4
   add      r1, r1, #4
   ldr      r2, [r1]
   str      r2, [r0]      @ r2
   add      r0, r0, #4
   add      r1, r1, #4
   ldr      r2, [r1]
   str      r2, [r0]      @ r3
   add      r0, r0, #36
   add      r1, r1, #4
   ldr      r2, [r1]
   str      r2, [r0]      @ r12
   add      r0, r0, #8
   add      r1, r1, #4
   ldr      r2, [r1]
   str      r2, [r0]      @ lr_irq

   @ Copy all other general-purpose registers to memory
   sub      r0, r0, #40
   str      r4, [r0]      @ r4
   add      r0, r0, #4
   str      r5, [r0]      @ r5
   add      r0, r0, #4
   str      r6, [r0]      @ r6
   add      r0, r0, #4
   str      r7, [r0]      @ r7
   add      r0, r0, #4
   str      r8, [r0]      @ r8
   add      r0, r0, #4
   str      r9, [r0]      @ r9
   add      r0, r0, #4
   str      r10, [r0]      @ r10
   add      r0, r0, #4
   str      r11, [r0]      @ r11

   @ Switch to System Mode and save sp in memory
   add      r0, r0, #8
   mov      r1, #0x1f
   mrs      r2, cpsr
   msr      cpsr, r1
   str      sp, [r0]
   msr      cpsr, r2

   @ Copy the saved CPSR to memory
   ldr      r0, =_current_cpsr
   mrs      r1, spsr
   str      r1, [r0]

   @ Branch to kernel interrupt handler routine
   ldr      r0, =handle_intr
   bx      r0

   .global __schedule
@-------------------------------------------------------------------------------
__schedule:
@-------------------------------------------------------------------------------
   @ Copy BIOS-backuped registers to stack
   ldr      r0, =_current_regs
   sub      r1, sp, #24
   ldr      r2, [r0]
   str      r2, [r1]      @ r0
   add      r0, r0, #4
   add      r1, r1, #4
   ldr      r2, [r0]
   str      r2, [r1]      @ r1
   add      r0, r0, #4
   add      r1, r1, #4
   ldr      r2, [r0]
   str      r2, [r1]      @ r2
   add      r0, r0, #4
   add      r1, r1, #4
   ldr      r2, [r0]
   str      r2, [r1]      @ r3
   add      r0, r0, #36
   add      r1, r1, #4
   ldr      r2, [r0]
   str      r2, [r1]      @ r12
   add      r0, r0, #8
   add      r1, r1, #4
   ldr      r2, [r0]
   str      r2, [r1]      @ lr_irq

   @ Copy all other general-purpose registers from memory
   sub      r0, r0, #40
   ldr      r4, [r0]      @ r4
   add      r0, r0, #4
   ldr      r5, [r0]      @ r5
   add      r0, r0, #4
   ldr      r6, [r0]      @ r6
   add      r0, r0, #4
   ldr      r7, [r0]      @ r7
   add      r0, r0, #4
   ldr      r8, [r0]      @ r8
   add      r0, r0, #4
   ldr      r9, [r0]      @ r9
   add      r0, r0, #4
   ldr      r10, [r0]      @ r10
   add      r0, r0, #4
   ldr      r11, [r0]      @ r11

   @ Switch to System Mode and load sp from memory
   add      r0, r0, #8
   mov      r1, #0x1f
   mrs      r2, cpsr
   msr      cpsr, r1
   ldr      sp, [r0]
   msr      cpsr, r2

   @ Copy saved CPSR back from memory
   ldr      r0, =_current_cpsr
   ldr      r1, [r0]
   msr      spsr, r1

   @ Enable interrupts
   mov      r0,   #0x4000000
   add      r0,r0,#208
   mov      r1, #1
   strb   r1, [r0]

   @ Return to BIOS routine
   bx      lr

   .align
   .pool
   .end

Any help would be GREATLY appreciated.

#37825 - Vince - Thu Mar 17, 2005 2:04 pm

Hello,

As for multitasking/RTOS, I would advise you check eCos sources, the FSF RTOS. A search on the lists will give you pointers to the GBA port.

HTH,

Vince
_________________
Reclaim control of your F2A/F2AU with if2a !!

#37833 - Lord Graga - Thu Mar 17, 2005 5:41 pm

This has nothing to do with your problem, but I guess that you would like to know that:
Code:
   str      r2, [r0]
   add      r0, r0, #4

Can be shortened down to:
Code:
   str      r2, [r0], #4

#38018 - sasq - Sun Mar 20, 2005 2:11 pm

I guess we should also tell you about LDMIA and STMDB that lets you save any group of registers with one opcode. Neat eh?