📄 cxskv5t.asm
字号:
JMPR cc_UC,findready ;get next task in line, able to run
rescan6:
@IF( @SLICE_ENABLE )
jbc _cmx_flag1.2,findready ;should we do a time slice switch
@ENDI
midpaus2:
MOV R5,[R10+ #tcbstate] ;get the task's state
AND R5,#RESUME OR READY ;see if capable of running
JMPR cc_NZ,task_resume ;yes, go let task run
findready:
MOV R10,[R10+#nxttcb] ;get next task in linked list
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
CALLA cc_UC,_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 ) ;is time slice code testing enabled?
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
CALLA cc_UC,_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 )
CALLA cc_UC,__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
RETN ;return to correct address
restore_from_interrupt:
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_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 NEAR
@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
RETN
_K_OS_Disable_Interrupts ENDP
_K_OS_Enable_Interrupts PROC NEAR
@IF( @INT_ENABLE )
BFLDH PSW,#0F0H,#00h
@ELSE
BSET IEN ;turn interrupts ON
@ENDI
RETN
_K_OS_Enable_Interrupts ENDP
_K_OS_Save_Interrupts PROC NEAR
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
RETN
_K_OS_Save_Interrupts ENDP
_K_OS_Restore_Interrupts PROC NEAR
MOV PSW,_ie_holder
RETN
_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 NEAR
add SP,#2 ;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 NEAR
add SP,#2 ;adjust stack pointer for calls to K_OS_Intrp_Exit
NOP ;has to be here for silicon
@IF( @Ff_ENABLE )
CALLA cc_UC,__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 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_flag1.7,done1_scheduler ;have we entered CMX RTOS
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 + #2] ;get psw
AND R2,#0F000H ;see if other interrupts preempted
jmpr cc_NZ,done_scheduler ;yes, go finish their code
no_pending:
MOVB RL1,_locked_out ;see if we were in critical region
JMPR cc_NZ,done_scheduler ;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,done_scheduler ;see if we should enter K_I_Scheduler
jmp_sched_int:
movb rl1,#01h ;yes, set critical region count to 1
addb _locked_out,rl1
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 ;save additional task's regs, that may be used
MOV [-R0],R1
MOV MDC,#00h
MOV R1,MDH
MOV [-R0],R1
MOV R1,MDL
MOV [-R0],R1
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
_K_OS_Intrp_Exit ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CXSKV5T_PR ENDS
REGDEF R0-R15
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -