📄 cxskv5s.asm
字号:
CMP R10,#_cmx_tcb ;see if at end of list
; this will now loop thru ALL tcb's, before testing do_int_pipe
; and do_K_I_Timer_Task
JMPR cc_NE,midpaus2 ;no, continue
@IF( @LOW_POWER_ACTIVE )
jnb _cmx_flag1.6,no_power_down
power_down:
PUSH R10 ;save pointer
CALLS SEG _K_OS_Low_Power_Func,_K_OS_Low_Power_Func ;go to power down mode (user written)
POP R10 ;restore pointer
no_power_down:
@ENDI
MOV R10,[R10 + #nxttcb] ;set r10 to highest priority user task
JMPR cc_UC,rescan1 ;test flags again
task_resume:
BFLDL _cmx_flag1,#(idle_flag OR do_time_slice),#00h
@IF( @INT_ENABLE )
BFLDH PSW,#0F0H,#(INT_LEVEL << 4)
@ELSE
BCLR IEN ;turn interrupts off
@ENDI
@IF( @ADD_NOP )
NOP ;These 2 NOP's fix the 80C16x silicon
NOP
@ENDI
MOVB RL4,_cmx_flag1 ;get CMX flag byte
ANDB RL4,#(do_int_pipe or do_timer_tsk) ;see if either flag set
JMPA cc_NZ,sched_again ;if so, go do it
resume_good:
MOVB _locked_out,ZEROS ;set locked out to zero
;move the tcb address into current active tcb
MOV _activetcb,R10 ;load tcb pointer with pointer
MOVB RL4,[R10+#tsk_priority] ;get tasks priority
MOVB _active_priority,RL4 ;store it
@IF( @SLICE_ENABLE )
MOVB RL4,_SLICE_ON ;see if time slice user enabled
JMPR cc_Z,no_slice ;no, bypass following
jb _cmx_flag1.3,no_slice
bset _cmx_flag1.3
MOVB RL4,_TSLICE_SCALE ;get time slice scale count
MOVB _tslice_count,RL4 ;load it
no_slice:
@ENDI
@IF( @CMXTRACKER_ENABLE )
CMP R10,_previoustcb ;see if same task as before
JMPR cc_EQ,same1
diff1:
MOV _previoustcb,R10
PUSH R10 ;save pointer
CALLS SEG _cmxtracker_in_task,_cmxtracker_in_task
POP R10 ;restore pointer
same1:
@ENDI
MOV R4,[R10+#tcbstate] ;get task's states again
@IF( @CMXTRACKER_ENABLE )
MOV R5,R4
@ENDI
BFLDH R4,#0EH,#08H ;set to RUNNING STATE
MOV [R10+ #tcbstate],R4 ;save it
jb r5.9,task_ready ;see if READY, then task start
;at beginning brace
;if not, then task is RESUMING
mov R0,[R10+#stk_save] ;get the task's stack address
MOV R2,[R0+] ;GET COUNT
restore_loop:
MOV R1,[R0+] ;GET WORD FROM USER STACK
PUSH R1 ;PUT ON SYSTEM STACK
SUB R2,#2
JMPR cc_NZ,restore_loop
@IF( @FLOAT_ENABLE )
CALLS SEG __fppopus,__fppopus
@ENDI
MOV R15,[R0+] ;restore all regs
MOV R14,[R0+]
MOV R13,[R0+]
MOV R12,[R0+]
MOV R11,[R0+]
MOV R10,[R0+]
MOV R9,[R0+]
MOV R8,[R0+]
MOV R7,[R0+]
MOV R6,[R0+]
MOV R5,[R0+]
MOV R4,[R0+]
MOV R3,[R0+]
; new as of 9/29/93
pop psw ;restore psw, for MULIP bit
JB PSW.6,restore_from_interrupt ;see if interrupt caused task
;switch, if so jump
MOV R2,[R0+]
MOV R1,[R0+]
pop psw ;restore TRUE PSW
RETS ;return to correct address
restore_from_interrupt:
MOV R1,[R0+] ;restore additional regs
MOV DPP2,R1
MOV R1,[R0+]
MOV DPP0,R1
MOV R1,[R0+] ;restore additional regs
mov mdl,r1
MOV R1,[R0+]
mov mdh,r1
MOV R1,[R0+]
mov mdc,r1
done_scheduler:
MOV R2,[R0+]
MOV R1,[R0+]
done1_scheduler:
@IF( @FIX166 )
BFLDH PSW,#0F0H,#0F0H ;This fixes the 8016x silicon
NOP
NOP
@ENDI
FAKE_RETI ;return to correct address, use literal,
;so assembler will be happy
RET ;DUMMY Return instruction, to keep assembler happy
; the following is for a task that is beginning it's code
task_ready:
mov R0,[R10+#stk_start] ;load the task's beginning stack address
mov R1,#0800h ;load in value to enable interrupts
;for psw (set bit IEN)
push R1 ;place on stack
mov r4,[R10+#task_addr_seg] ;place task's address on stack
push R4
mov r4,[R10+#task_addr_sof] ;place task's address on stack
push R4
@IF( @FIX166 )
BFLDH PSW,#0F0H,#0F0H ;This fixes the 8016x silicon
NOP
NOP
@ENDI
FAKE_RETI ;return to correct address, use literal,
;so assembler will be happy
RET ;DUMMY Return instruction, to keep assembler happy
_K_I_Sched ENDP
_K_OS_Disable_Interrupts PROC FAR
@IF( @INT_ENABLE )
BFLDH PSW,#0F0H,#(INT_LEVEL << 4)
@ELSE
BCLR IEN ;turn interrupts off
@ENDI
@IF( @ADD_NOP )
NOP ;These 2 NOP's fix the 80C16x silicon
NOP
@ENDI
RETS
_K_OS_Disable_Interrupts ENDP
_K_OS_Enable_Interrupts PROC FAR
@IF( @INT_ENABLE )
BFLDH PSW,#0F0H,#00h
@ELSE
BSET IEN ;turn interrupts ON
@ENDI
RETS
_K_OS_Enable_Interrupts ENDP
_K_OS_Save_Interrupts PROC FAR
PUSH R2 ;save R2
PUSH PSW
@IF( @INT_ENABLE )
BFLDH PSW,#0F0H,#(INT_LEVEL << 4)
@ELSE
BCLR IEN ;turn interrupts off
@ENDI
@IF( @ADD_NOP )
NOP ;These 2 NOP's fix the 80C16x silicon
NOP
@ENDI
POP R2
MOV _ie_holder,R2
POP R2
RETS
_K_OS_Save_Interrupts ENDP
_K_OS_Restore_Interrupts PROC FAR
MOV PSW,_ie_holder
RETS
_K_OS_Restore_Interrupts ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Interrupt routine
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; NOTE: for ALL memory models, except tiny. Must be CALLS instruction
; the following is for "C" coded interrupts using #pragma noframe
_K_OS_Intrp_Exit_No_Frame PROC FAR
add SP,#4 ;adjust stack pointer for calls to K_OS_Intrp_Exit
jmpa cc_UC,K_OS_Intrp_Exit1
RET ;NOTE: This will NOT be executed, here only to suppress
;a warning from the assembler
_K_OS_Intrp_Exit_No_Frame ENDP
; the following is for "C" coded interrupts NOT using #pragma noframe
_K_OS_Intrp_Exit PROC FAR
add SP,#4 ;adjust stack pointer for calls to K_OS_Intrp_Exit
NOP ;has to be here for silicon
@IF( @Ff_ENABLE )
CALLS SEG __fppopus,__fppopus
@ENDI
@IF ( @MDH_PUSHED_FIRST )
POP MDL ;restore registers that compiler generated code pushed
POP MDH
@ELSE
POP MDH ;restore registers that compiler generated code pushed
POP MDL
@ENDI
POP DPP2
POP DPP0
POP MDC
@IF( @PSW_INT_PUSH )
POP PSW
@ENDI
POP CP
K_OS_Intrp_Exit1:
@IF( @INT_ENABLE )
BFLDH PSW,#0F0H,#(INT_LEVEL << 4)
@ELSE
BCLR IEN ;turn interrupts off
@ENDI
@IF( @ADD_NOP )
NOP ;These 2 NOP's fix the 80C16x silicon
NOP
@ENDI
jnb _cmx_active,done1_scheduler
MOV [-R0],R1 ;save reg
MOV [-R0],R2 ;save reg
mov r1,sp ;get stack address
; test ILVL level of psw. If non zero, means other interrupts were interrupted
mov r2,[r1 + #4] ;get psw
AND R2,#0F000H ;see if other interrupts preempted
jmpr cc_NZ,done_scheduler ;yes, go finish their code
no_pending:
PUSH DPP2
MOV DPP2, #PAG C166_DGROUP
NOP
MOVB RL1,_locked_out ;see if we were in critical region
JMPR cc_NZ,new_exit ;yes, return to it
MOVB RL1,_cmx_flag1 ;get CMX flag byte
ANDB RL1,#(do_int_pipe or preempted or do_timer_tsk or do_time_slice or do_coop_sched)
JMPR cc_Z,new_exit ;yes, return to it
jmp_sched_int:
movb rl1,#01h ;yes, set critical region count to 1
addb _locked_out,rl1
POP DPP2
AND PSW,#0FFFH ;clear ilvl level
BSET PSW.6 ;set user flag, identifying that interrupt cause preemption
; the following pushes PSW on stack, saving MULIP bit and USER flag then
; enables interrupts.
SCXT PSW,#0800H
MOV R1,MDC
MOV [-R0],R1
MOV MDC,#00h
MOV R1,MDH
MOV [-R0],R1
MOV R1,MDL
MOV [-R0],R1
MOV R1,DPP0
MOV [-R0],R1
MOV R1,DPP2
MOV [-R0],R1
MOV DPP0, #PAG ?BASE_DPP0 ; Set data page pointer.
MOV DPP2, #PAG ?BASE_DPP2 ;
jmpa cc_UC,sched_int ;go save task's context
RET ;NOTE: This will NOT be executed, here only to suppress
;a warning from the assembler
new_exit:
POP DPP2
JMPA cc_UC,done_scheduler
_K_OS_Intrp_Exit ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CXSKV5S_PR ENDS
C166_DGROUP DGROUP __DUMMY
__DUMMY SECTION DATA WORD PUBLIC 'CNEAR'
__DUMMY ENDS
REGDEF R0-R15
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -