David Armour

Assembly code help needed

Discussion created by David Armour on Oct 27, 2008
Latest reply on Oct 29, 2008 by Tony Papadimitriou
I have written a very simple round robin tasker that changes tasks on a timer interrupt. The tasks control blocks (a struct) that holds nothing more than a stack, a stack pointer and a 'Next' pointer to the next task in the list. I also have a global pointer called 'CurrentTask' that points to the current task control block. In the interrupt I just want to preserve the stack pointer, move to the next task, get the new stack pointer and do an RTI. One would think this is simple enough to do but for some reason when I switch to the second task I end up somewhere I should not be. Can anyone see something I am missing?
 
typedef struct TCB
{
    char *StackPtr;
   struct TCB *Next;
   char  Stack[STACK_DEPTH];   // stack
};

 
struct TCB *CurrentTask;

 
ISR(TaskTimerInt_Interrupt)
{
    /* RTCSC: RTIF=1 */
    setReg8Bits(RTCSC, 0x80);            /* Reset real-time counter request flag */
 
    __asm pshh;                        // push H on the stack
    __asm tsx;                           // preserve the value of the stack pointer in H:X
    __asm sthx CurrentTask;    // store the stack pointer
   
    __asm ldhx CurrentTask;    // load H:X with the value pointed to by CurrentTask
    __asm aix #2;                      // add 2 to equal the location of Next (see typedef)
    __asm sthx CurrentTask;   // store the Next value into CurrentTask
   
    __asm ldhx CurrentTask;   // load the CurrentTask stack pointer value in H:X
    __asm txs;                          // store H:X into the SP
    __asm pulh;                        // pull H
    __asm rti;                           // return from interrupt
}

Outcomes