; File : OS_CPU_A.ASM ; By : Dan Lewis ;***************************************************************************** ; ; Intel x86 Specific code ; Protected Mode, Flat Memory Model ; ; DJGPP and NASM ; (IBM/PC Compatible Target) ; ;***************************************************************************** SECTION .data EXTERN _OSIntNesting EXTERN _OSPrioHighRdy EXTERN _OSPrioCur EXTERN _OSRunning EXTERN _OSTCBCur EXTERN _OSTCBHighRdy EXTERN _OldTickISR SECTION .text ALIGN 16 BITS 32 GLOBAL _OSTickISR GLOBAL _OSStartHighRdy GLOBAL _OSCtxSw GLOBAL _OSIntCtxSw EXTERN _OSIntExit EXTERN _OSTimeTick EXTERN _OSTaskSwHook ; -------------------------------------------------------------------- _OSStartHighRdy: ; START MULTITASKING ; -------------------------------------------------------------------- CALL _OSTaskSwHook ; Call user defined task switch hook MOV BYTE [_OSRunning], 1 ; Indicate that multitasking has started MOV EAX, [_OSTCBHighRdy] ; ESP = OSTCBHighRdy->OSTCBStkPtr MOV ESP, [EAX] POPA ; Load task's context IRET ; Run task ; -------------------------------------------------------------------- _OSCtxSw: ; PERFORM A CONTEXT SWITCH (From task level) ; -------------------------------------------------------------------- PUSHA ; Save current task's context MOV EAX, [_OSTCBCur] ; OSTCBCur->OSTCBStkPtr = ESP MOV [EAX], ESP ; Fall through to _OSInCtxSw... ; -------------------------------------------------------------------- _OSIntCtxSw: ; PERFORM A CONTEXT SWITCH (From an ISR) ; -------------------------------------------------------------------- CALL _OSTaskSwHook ; Call user defined task switch hook MOV AL, [_OSPrioHighRdy] ; OSPrioCur = OSPrioHighRdy MOV [_OSPrioCur], AL MOV EAX, [_OSTCBHighRdy] ; OSTCBCur = OSTCBHighRdy MOV [_OSTCBCur], EAX MOV ESP, [EAX] ; ESP = OSTCBHighRdy->OSTCBStkPtr POPA IRET ; Return to new task ; -------------------------------------------------------------------- _OSTickISR: ; -------------------------------------------------------------------- PUSHA ; Save interrupted task's context INC BYTE [_OSIntNesting] ; Notify uC/OS-II of ISR CMP BYTE [_OSIntNesting], 1 ; if (OSIntNesting == 1) JNE SHORT _OSTickISR1 MOV EAX, [_OSTCBCur] ; OSTCBCur->OSTCBStkPtr = ESP MOV [EAX], ESP _OSTickISR1: PUSHF PUSH CS CALL DWORD [_OldTickISR] CALL _OSTimeTick ; Process system tick CALL _OSIntExit ; Notify uC/OS-II of end of ISR POPA IRET ; Return to interrupted task END