⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cxskv5t.asm

📁 上传一个带源代码的嵌入式实时多任务操作系统CMX
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	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 + -