📄 skd.ori
字号:
; if (tcb_ptr -> sk_time_slice > 0)
TST.L $01C(A5)
BLE _No_Timer_Stop
; CLD_Stop_System_Timer();
BSR CLD_Stop_System_Timer
_No_Timer_Stop:
;
; /* Place the saved stack value in SKP_Save_Stack_Ptr into this tasks
; TCB. */
; tcb_ptr -> sk_stack_ptr = SKD_Task_Stack_Ptr;
;
MOVE.L SKD_Task_Stack_Ptr,$030(A5)
;
; /* Show that the system is active. This is done at the bottom. */
; SKP_Current_Task_ID = NU_SYSTEM;
MOVEQ.L #-1,D0
MOVE.L D0,SKP_Current_Task_ID
;
; /* Return to executive scheduling loop. */
JMP _SKP_Schedule_Loop
;} /* end of SKD_Control_To_Exec */
;
;
;
;/************************************************************************/
;/* */
;/* FUNCTION "SKD_Interrupt_Context_Save" */
;/* */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function is responsible for saving off the current system */
;/* context on the current stack in prepartion of processing an */
;/* interrupt. If the interrupt occurred during task execution, */
;/* the task stack pointer "SKP_Save_Stack_Ptr" is set to the */
;/* current stack pointer. */
;/* */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Accelerated Technology */
;/* */
;/* CALLED FROM */
;/* */
;/* Interrupt handlers that invoke C routines or might cause */
;/* context switching */
;/* */
;/* ROUTINES CALLED */
;/* */
;/* None */
;/* */
;/* INPUTS */
;/* */
;/* None */
;/* */
;/* OUTPUTS */
;/* */
;/* Stack pointers */
;/* SKP_Current_Task_ID */
;/* */
;/************************************************************************/
;void SKD_Interrupt_Context_Save()
;
;{
export SKD_Interrupt_Context_Save
SKD_Interrupt_Context_Save
;
; Handle nested interrupts of different priorities (1-6). Note that routines
; inside an Interrupt Service Routine (ISR) must not enable interrupts of
; the same or lower levels. It is assumed that the ISR return address is
; sitting directly on top of the interrupt stack frame.
;
; CLR.L D0 ; Possible bug fix - July 9, 1993
MOVE SR,-(A7) ; Push the SR on the stack
ORI #$0700,SR ; Lockout all interrupts
MOVE.W (A7)+,SKD_Save_SR ; Save the SR only while lockout
MOVE.L D0,-(A7) ; Save D0 on the current stack
MOVE.L #$0700,D0 ; Put interrupt level mask in D0
AND.W 8(A7),D0 ; Pickup the interrupted level
BEQ _Normal_Context_Save ; Normal interrupt context save
;
; A nested interrupt has occurred
;
MOVE.L A0,-(A7) ; Save A0 on the current stack
MOVE.W SKD_Save_SR,D0 ; Pick up the current saved SR
ROR #8,D0 ; Shift the interrupt level down
ANDI.L #7,D0 ; And out extra bits
LEA SKD_Interrupt_Level,A0 ; Get base of interrupted level
; table
ADDA.L D0,A0 ; Build offset to the exact byte
MOVE.L 8(A7),D0 ; Pickup the return address, D0
; is pushed back on stack later
ADDQ.B #1,(A0) ; Increment the nested interrupt
; counter for this level
BVS IND_Major_System_Error ; If more than 256 nests, error
CMPA.L SKD_System_Stack_Ptr,A7 ; Is the current stack the system?
BLT _Save_And_Return ; Yes, save context and return
ADDA.L #8,A0 ; Offset to the stack switch flag
MOVE.B #1,(A0) ; Set the flag to indicate that
; nested and stack switch
MOVE.L A7,SKD_Task_Stack_Ptr ; Save the task stack pointer
MOVE.L SKD_System_Stack_Ptr,A7 ; Switch to the system stack ptr
_Save_And_Return:
MOVE.L #-1,SKP_Current_Task_ID ; Set task ID to system
MOVEM.L D1-D7/A1-A6,-(A7) ; Save remainder of the context
MOVE.L D0,-(A7) ; Finally, push the return address
; on current stack
MOVE SKD_Save_SR,SR ; Restore the SR of this ISR
RTS ; Return to caller
;
_Normal_Context_Save:
MOVE.L (A7)+,D0 ; Recover D0 from the stack
;
; /* Check to see if a task is active. */
; if (SKP_Current_TCB_Ptr != NU_NULL)
; {
;
; /* Set the current task ID to NU_SYSTEM. */
TST.L SKP_Current_TCB_Ptr ; Is there a task active?
BEQ _No_Task_Context_Save ; No, interrupted in executive
;
; /* Save registers off. */
SUBQ.L #4,A7 ; Get a place on the stack
MOVE.L A5,(A7)+ ; Save A5 before using it
MOVEA.L (A7),A5 ; Pick up the return address
MOVE.L A6,(A7) ; Save A6 on the stack
SUBQ.L #4,A7 ; Position Stack Pointer to Top
MOVEM.L D0-D7/A0-A4,-(A7) ; Save the rest of the registers
MOVE.W #1,-(A7) ; Put interrupt stack ID on Top
;
; SKP_Current_Task_ID = NU_SYSTEM;
;
MOVEQ.L #-1,D0 ; Put NU_SYSTEM into D0
MOVE.L D0,SKP_Current_Task_ID ; Set the Task ID variable to sys
;
; /* Save the task's stack pointer. */
;
MOVE.L A7,SKD_Task_Stack_Ptr ; Save the task stack pointer
;
; /* Switch to executive's stack. */
;
MOVE.L SKD_System_Stack_Ptr,A7 ; Switch to the system stack ptr
MOVE.L A5,-(A7) ; Put the return address on the
; System stack
;
; }
_No_Task_Context_Save:
MOVE SKD_Save_SR,SR ; Restore the original SR
RTS ; Return to interrupt handler
;}
;
;
;
;/************************************************************************/
;/* */
;/* FUNCTION "SKD_Interrupt_Context_Restore" */
;/* */
;/* */
;/* DESCRIPTION */
;/* */
;/* This function is responsible for restoring the current system */
;/* context from the current stack in prepartion of processing an */
;/* interrupt return. */
;/* */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Accelerated Technology */
;/* */
;/* CALLED FROM */
;/* */
;/* Interrupt handlers that invoke C routines or might cause */
;/* context switching */
;/* */
;/* ROUTINES CALLED */
;/* */
;/* SKD_Control_To_Executive */
;/* */
;/* INPUTS */
;/* */
;/* None */
;/* */
;/* OUTPUTS */
;/* */
;/* Stack pointers */
;/* */
;/************************************************************************/
;void SKD_Interrupt_Context_Restore()
;
;{
export SKD_Interrupt_Context_Restore
SKD_Interrupt_Context_Restore
;
; SKD_Interrupt_Context_Restore assumes that the saved information is at
; the top of the stack. Hence, ISR should call this routine via a JMP
; instruction.
;
MOVE SR,-(A7) ; Push the SR on the stack
ORI #$0700,SR ; Lockout all interrupts
MOVE.W (A7)+,D0 ; Pick up the current SR
ROR #8,D0 ; Shift the interrupt level down
ANDI.L #7,D0 ; Clear out garbage bits
LEA SKD_Interrupt_Level,A0 ; Get base of interrupted level
; table
ADDA.L D0,A0 ; Build offset to the exact byte
MOVE.B (A0),D0 ; Pickup the interrupt level value
BEQ _Normal_Context_Restore ; If 0, interrupt not nested
; Otherwise, nested interrupt
MOVEM.L (A7)+,D1-D7/A1-A6 ; Restore registers
CMP.B #1,(A0) ; Interrupt nested, what type?
ADDA.L #8,A0 ; Nesting is complete, check for
; a stack switch
BNE _No_Stack_Switch ; No stack switch, on int stack
CMP.B #1,(A0) ; Switch stacks?
BNE _No_Stack_Switch ; No, Skip over the stack swap
CLR.B (A0) ; Clear the stack switch flag
MOVE.L SKD_Task_Stack_Ptr,A7 ; Recover original stack pointer
_No_Stack_Switch:
SUBA.L #8,A0 ; Position back to nested count
SUBQ.B #1,(A0) ; Decrement nested interrupt count
MOVE.L (A7)+,A0 ; Recover A0 from stack
MOVE.L (A7)+,D0 ; Recover D0 from stack
ADDQ.L #4,A7 ; Position past first return addr
RTE ; Return from exception
_Normal_Context_Restore:
;
; /* Check to see if a task was active. */
; if (SKP_Current_TCB_Ptr != NU_NULL)
; {
;
; /* Check for context switching. */
TST.L SKP_Current_TCB_Ptr ; See if TCB pointer is NULL
BEQ _Return_To_Executive ; If so, just return to executive
;
; if ((SKP_Current_TCB_Ptr -> sk_ready_prev != NU_NULL)
; (SKP_Current_TCB_Ptr -> sk_no_preempt == NU_FALSE))
; {
;
; /* Call SKD_Control_To_Executive to make the context switch. */
;
MOVE.L SKP_Current_TCB_Ptr,A0 ; Pickup the TCB address
CMPA.L SKP_Ready_List_Ptr,A0 ; Compare it to the head of list
BEQ _Return_To_Task ; If equal, just return to task
MOVE.L 8(A0),D0 ; See if task was suspended
BNE SKD_Control_To_Executive ; Transfer control to executive
MOVE.L 24(A0),D0 ; Pickup no-preempt flag
BNE _Return_To_Task ; If set, just return to task
;
; SKD_Control_To_Executive();
;
JMP SKD_Control_To_Executive ; Otherwise, return to Nucleus
;
; }
; else
; {
_Return_To_Task:
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -